Suppose I'm testing a function and I want my function to display some information about itself ONLY IF a test doesn't pass.
I don't want to alter the flow of the function while saving data for latter use.
function foo(input){
//normal work of the function
//save the value of variable A
//normal work of the function
//save the value of variable B
//normal work of the function
}
This would be a test
fooTest(){
var condition = foo();
//display variable A and B depending on the value of the condition
}
How do I do it?
In my case, I'm testing functions and I want them to show me their value if their tests fails. If they don't fail I don't want to display information on the screen.
You might want to use a closure to preserve the value of variable after the function has been executed.
function set(A, B) {
// perform your operation
let a = A;
let b = B;
// The nested scope will remember the parent's scope
const getA = function() { return a; }
const getB = function() { return b; }
return { getA, getB };
}
var obj = set(10, 20);
console.log(obj.getA());
console.log(obj.getB());
this could be a good place do use .call() in order to alter this context:
function foo(input){
//normal work of the function
this.A = 10;
//normal work of the function
this.B = 20;
//normal work of the function
}
function fooTest() {
let obj = {};
let condition = foo.call(obj);
console.log(obj.A, obj.B);
}
fooTest()
Related
I have a function which has other functions defined:
var A = function(n) {
console.log(n + A.num());
}
A.num = function() {
return 5;
}
I want to change the name to B and delete A:
var B = A;
A = undefined;
But, when I do B(), It gives an error throws: "Cannot read property 'num' of undefined", which is completely normal and expected.
How do I handle this?
PS: Anyone who thinks that changing A.num() with this.num(), It will not work
You can always refer to the current function using its explicit name (if it has one).
So, change the definition, to name the function, and refer to it using that:
var A = function currentFunction(n) {
console.log(n + currentFunction.num());
}
A.num = function() {
return 5;
}
var B = A;
A = undefined;
B(10); //15
console.log(typeof currentFunction) //undefined, function name is local
Note: the abovementioned approach won't work if the function is named implicitly, but will continue to work if the function is renamed via fn.name
Alternatively, if the function isn't an arrow function, you can also use arguments.callee, that will work even with anonymous functions, but its use isn't recommended:
var A = function (n) {
console.log(n + arguments.callee.num());
}
A.num = function() {
return 5;
}
var B = A;
A = undefined;
B(10); //15
Unfortunately, none of the above will work with arrow functions, if you want to refer to itself, use a named bound function expression instead.
actually that's normal, because in js you can't really copy object
// Define object bar
var bar = {
x : 'Hi'
}
console.log(bar.x); //Hi
// Assign it to foo
var foo = bar;
console.log(foo.x); //Hi
//But
foo.x = 'Hello!! Im foo.';
console.log(foo.x); //Hello!! Im foo.
console.log(bar.x); //Hello!! Im foo.
bar.x = "Nice to meet you foo!!";
console.log(foo.x); //Nice to meet you foo!!
console.log(bar.x); //Nice to meet you foo!!
you have to return a new one with the same value as the last
var foo = {...bar};
and this is not working because B is always calling 'num' from A that doesn't exist, One way to sever the parity would be stringify the initial function, then use a function constructor to create the clone after replacing the 'A' by 'B'
but tell me more why are you facing this problem ?
var A = function(n) {
if(!this.num){
console.log("This is not available coz obj is not created");
console.log("Below error is for testing purpose");
}
let a=this.num(n);
console.log(a);
}
//use prototype here
//A.num = function() {
A.prototype.num=function(n){
return n+5;
}
//use new to create object
new A(5);
var B = A;
A = undefined;
//use new to create object
new B(6);
B(5);//lets try without using new keyword
.as-console-wrapper { max-height: 100% !important; top: 0; }
If I wanted to first declare a function, and then at some point I want to reference the function and not its return value to a variable, how would I do that?
var best = bestPresidentEver;
function bestPresidentEver(a,b){
//for some reason always returns Trump.
}
and then call best(a,b) instead of bestPresidentEver(a,b)
I am wondering how to do that opposed to assigning the function to the var upon declaration.
var best =
function bestPresidentEver(a,b){
//for some reason always returns Trump.
}
Declare your variable like this
var bestPresidentEver= function (a,b){
//for some reason always returns Trump.
return "Trump"; //:D
}
Then call that function like this
//You have to declare a and b variables
var trumpHere = bestPresidentEver(a,b);
If your function is already declared, just assign it to the variable :
function bestPresidentEver (a,b){
//for some reason always returns Trump.
return "Trump"; //:D
}
var trumpHere = bestPresidentEver;
Then call it like this :
var trumpAgain = trumpHere(a, b);
If the variable exists and it's not a const you can simply reassign it's value to the function itself.
Ex
var foo = 'foo';
function bar(a) {
return 'example ' + a;
}
bar('code'); //=> "example code"
/* Further down, reassign the `foo` variable */
foo = bar;
foo('code, again'); //=> "example code, again"
I am using SignalR, and I need to point it to a function, and I also want to call that function in other areas of the application.
If the library expects a function parameter, you can simply pass that function like so.
function first(next /* expects a function parameter */) {
return next('hello');
}
function second(prefix) {
return prefix+ ' world!';
}
first(second); //=> "hello world!"
I'm new to functional programming and I'm trying to learn it in javascript. I found some examples and wrote my own snippet, but I don't understand WHY it works. There is a function called whatTheHeckIsThis. Can someone tell me what it is doing or what its purpose is? Note that when running this code, the output is true.
function boolFlipper(someFn){
return function whatTheHeckIsThis(x,y){
return !someFn(x,y);
};
}
var checkStrings = function(x, y){
return x === y;
}
var flipperTester = boolFlipper(checkStrings);
var str1 = "this string";
var str2 = "that string";
console.log(flipperTester(str1, str2));
My confusion is why can't I just do this instead:
function boolFlipper(someFn){
return !someFn(x,y);
}
a reference to whatTheHeckIsthis() will be returned and stored into flipperTester
After this, flipperTester can be used like a function.
You can use this language feature to abstract some code.
Simple example:
function addTen(x) { return x + 10 }
function multiplyByTen(x) { return x * 10 }
...
var doMath
// somewhere a user selected something
if (userInputSaysAdd) doMath = addTen
if (userInputSaysMultiply) doMath = multiplyByTen
// this will be the choosen function
doMath(someValue)
Your second version doesn't work for 2 reasons:
The purpose of boolFlipper is to return a new function, which you can assign to another variable and later call.
Your function doesn't have x and y parameters.
To solve #2 you could write:
function boolFlipper(someFn, x, y) {
return !someFn(x, y);
}
You would then have to call it like:
console.log(boolFlipper(checkStrings, str1, str2));
But you still couldn't do:
flipperTester = boolFlipper(checkStrings);
The original snippet returns a closure, which is bound in the environment where someFn is equal to the function passed as an argument to bookFlipper(). You can then assign this function to a variable, and call it with new arguments, that are assigned to x and y, and then the the function saved in someFn() is called, the return value is negated with !, and this is returned.
For more information about closures, see How do JavaScript closures work?
In JavaScript functions are objects, so you can return them. When you return a function you are getting a function object, so you can call it as any other function. For example:
function myFun() {
return function() {
console.log("test");
};
}
var functionInside = myFun();
/* This is like doing:
var functionInside = function() {
console.log("test");
};
*/
functionInside(); // This will execute the function.
Example with your code:
This variable:
var flipperTester = boolFlipper(checkStrings);
contains a function like this:
var flipperTester = function (x,y) {
return !someFn(x,y);
}
And this is something similar to
function flipperTester(x,y) {
return !someFn(x,y);
}
So when you do:
flipperTester(str1, str2)
You are executing that function. The variable "someFn" inside there is the function "checkStrings", because you passed it when you initialize flipperTester variable.
boolFlipper is, for our purposes here, a function decorator: it takes a function and modifies it to do something else. A more instructive example might be a logging function:
var alsoLogs = f => (...args) => {
var result = f(...args);
console.log(result);
return result;
};
// now we have a function that adds 2 numbers:
var add = function add(a, b) { return a + b; };
// and we want to also log the result
var addAndLog = alsoLogs(add); // addAndLog is a function, would be the whatTheHeckIsThis from your example
addAndLog(2, 3); // logs 5 to the console
If you don't understand all the ES6 syntax that's ok, just understand that alsoLogs take a function f and returns a function that does the exact same thing as f but also logs the result to the console.
Since we as programmers are lazy, we don't want to have to write functions to glue together other functions every time we want to do this, so we write a function to do it for us, compose.
So now we can just say something like:
var addAndLog = R.compose(console.log, add);
addAndLog(2, 3); // logs 5 to the console
Having seen a lot of pure functions and how they have no side effects, what would be an example of an impure function, which is always been antagonized as unstable and major source of error?
For example an impure function that has a side effect on a variable outside of its own scope:
var count = 0;
function increaseCount(val) {
count += val;
}
Or a function that returns different values for the same input because it evaluates a variable that is not given as parameter:
var count = 0;
function getSomething() {
return count > 0;
}
A pure function doesn’t depend on and doesn’t modify the states of variables out of its scope.
Concretely, that means a pure function always returns the same result given same parameters. Its execution doesn’t depend on the state of the system.
var values = { a: 1 };
function impureFunction ( items ) {
var b = 1;
items.a = items.a * b + 2;
return items.a;
}
var c = impureFunction( values );
// Now `values.a` is 3, the impure function modifies it.
Here we modify the attributes of the given object. Hence we modify the object which lies outside of the scope of our function: the function is impure.
var values = { a: 1 };
function pureFunction ( a ) {
var b = 1;
a = a * b + 2;
return a;
}
var c = pureFunction( values.a );
we simply modify the parameter which is in the scope of the function, nothing is modified outside!
var values = { a: 1 };
var b = 1;
function impureFunction ( a ) {
a = a * b + 2;
return a;
}
var c = impureFunction( values.a );
// Actually, the value of `c` will depend on the value of `b`.
// In a bigger codebase, you may forget about that, which may
// surprise you because the result can vary implicitly.
Here, b is not in the scope of the function. The result will depend on the context: surprises expected!
var values = { a: 1 };
var b = 1;
function pureFunction ( a, c ) {
a = a * c + 2;
return a;
}
var c = pureFunction( values.a, b );
// Here it's made clear that the value of `c` will depend on
// the value of `b`.
Reference : For more details, click here
Math.random() is an impure function; it changes the internal state of the Math object so you get different values on successive calls. console.log() and alert() are impure functions because they have side effects (although they generate the same behavior and always return the same value for identical calls).
Any function that changes the internal state of one of its arguments or the value of some external variable is an impure function. This includes closures where calling a method changes the internal state of the closure itself:
let nextInt = (function() {
var i = 0;
return function() {
return i++;
};
})();
let a = nextInt(); // sets a to 0
let b = nextInt(); // sets b to 1
// etc.
Where'd you get the idea that impure functions are always considered a bad thing?
Impure functon is a function which returns different result for
same input parameters, that is to say that it depends on some state;
Function that may return same result for same input parameters, but
that mutates other state object. object that it does not depends but others do // causes side effects
example:
1)
var toggled = false; /* state */
/*impure function*/
function impureFn(number){
if(number%2 == 0)
toggled = true;
return toggled;
}
/*Execute this in order */
impureFn(5) // returns false
impureFn(2) //returns true
impureFn(5) // now returns true
An example i can think of (that is indeed quite confusing) is Array#reverse(). Instead of returning a new array, it modifies it in place while returning the original array.
Some other array functions do this as well, such as splice, push, shift, pop, unshift.
pure function (get argument and return new value):
function (objectArgument) {
return {
value: objectArgument.value + 123,
// other arguments
};
}
impure function (get argument, modified it and return modified object):
function (objectArgument) {
objectArgument.value += 123;
return objectArgument;
}
Basically I want to do this:
someFunction() // do something
someFunction.somePropertyFunction()
someFunction() // Now someFunction is modified; it should now exhibit a different behaviour
Is this possible?
EDIT:
I'm not looking for what #Kolink was suggesting. Basically I want to augment a function's functionality by calling one of it's property function.
Specifically, I need to: 1. have access to the original function inside my property function (which is entirely doable using this), and 2. bind a new function to the original function's name (which I'm not sure if it's possible).
Just to be clear, I don't have access to the internal definition of the function that I want to augment. I want to attach a function to Function.prototype (so that it will be available as a property of the function that I want to augment), and then I will call func.augmentThis(), and then func should be augmented. But I'm not sure how, hence the question :P
Easily. Here's an example:
var derp = 123;
someFunction = function() {alert(derp);};
someFunction.somePropertyFunction = function() {derp = 456;};
someFunction(); // alerts 123
someFunction.somePropertyFunction();
someFunction(); // alerts 456
Okay, that's an oversimplified example, but yeah, it's entirely possible.
If your question is whether a function attached as a property to another function has a way to access the function to which it is attached, the answer is no. After all, the same function could be attached to any number of functions of objects.
So one alternative is to explicitly refer to the "mother" function within the function that is attached to it and intended to change its behavior:
function f (n) { alert (n + f.offset); }
f.offset = 0;
f.change_offset = function (i) { f.offset = i; };
f (1); //1
f.change_offset (100);
f (1); //101
Here, f is hard-wired into the definition of change_offset. If this bothers you, or you want something slightly more general, write a little routine to set a function as a property on another function, while binding its this to the function being attached to:
function set_func_as_func_prop ( propname, func_to_set, func_to_set_on ) {
func_to_set_on[propname] = func_to_set.bind(func_to_set_on);
}
Now you can write the function more generally
function change_offset (i) {
this.offset = i;
}
and set it on f or any other function.
set_func_as_func_prop ("change_offset", change_offset, f);
set_func_as_func_prop ("change_offset", change_offset, g);
Sort of:
function someFunction() {
return realFunction.apply(this, arguments);
}
function someFunctionA(name) {
return 'Hello, ' + name + '!';
}
function someFunctionB(name) {
return 'Goodbye, ' + name + '...';
}
var realFunction = someFunctionA;
someFunction.somePropertyFunction = function () {
realFunction = someFunctionB;
};
Sure it's possible. It's not recommended, but it's possible. For example:
function a() {
alert("a");
}
function b() {
alert("b");
}
function c() {
return c.f.apply(this, arguments);
}
c.f = a;
c.toggle = function () {
c.f = c.f === a ? b : a;
};
Now let's test it:
c(); // alerts "a"
c.toggle();
c(); // alerts "b"
See the demo: http://jsfiddle.net/LwKM3/
I want to attach a function to Function.prototype. Then I need to bind a new function to the original function's name (which I'm not sure if it's possible).
That indeed is impossible, you don't know what refers to the function. And you cannot change the internal representation of a function, which is immutable.
The only thing you can do is to create a new function and return that, to let the caller of your method use it somehow - specifically assigning it to the original variable:
somefunction = somefunction.augmentSomehow();
Your method for that will look like this:
Function.prototype.augmentSomehow = function() {
var origFn = this;
return function() {
// in here, do something special
// which might include invoking origFn() in a different way
};
};
Not sure if this helps, but I would implement described problem in following way:
// defined by somebody else - unknown to developer
var someFunction = function() {
alert("this is initial behavior");
}
someFunction(); // returns "this is initial behavior"
// defines parent object on which someFunction() is called
var parentObject = this; // returns window object (as called direclty in the
// browser)
// if you are calling someFunction from some object (object.someFunction())
// it would be:
// var parentObject = object;
// augumentThis definition
someFunction.augumentThis = function() {
var newFunction = function() {
alert("this is changed behavior");
};
parentObject.someFunction.somePropertyFunction = function() {
parentObject.someFunction = newFunction;
parentObject.someFunction();
};
};
someFunction.augumentThis(); // change function behavior
someFunction(); // "this is initial behavior"
someFunction.somePropertyFunction(); // "this is changed behavior"
someFunction(); // "this is changed behavior"