What should be the value of final_answer in this Js code snippet and why?
function weird(x) {
var tmp = 3;
return function(y) {
return x + y + ++tmp;
}
}
var funny = weird(2);
var final_answer = funny(10);
I think value of final_answer is funny(10) because even though funny is 2+4+2 that is 8 but since that value is stored in a variable, we cannot call a variable like a function.
I don't know whether I'm correct or not.. If i'm wrong then please specify the reason why so that i can understand and not repeat this mistake.
When var funny = weird(2) is called, inside the function weird two variables are created, x with the value of 2 and tmp with the value of 3. Then a function object is created with the return statement. Code inside this function can access variables x and tmp. As this function object is then returned and assigned to variable funny which resides outside the function weird, a closure is created. This means that even though code outside of weird normally cannot access variables inside weird, the function object assigned to funny can do so.
As you call funny(10), the code calculates the sum of x with the value of 2, y with the value of 10 and the pre-incremented value 4 of tmp. So the final result is 16.
weird returns a function, which references the argument passed to weird. This is stored as funny. Calling funny (with an argument) calls the function returned from weird.
funny = weird(2);
funny(10)
>16
funny(5)
>12
funny(100)
>108
In other words, funny is the product of an anonymous function, and can be treated as though it were defined using function.
Related
I've been studying javascript examples and I came across this:
var numb=1;
function funName(numb){
// function work
return numb+1;
}
In this example I'm not sure how the number is iterating each time on return numb+1; I thought it would have to look more like numb=numb+1;
Does this just work cause the '+1' is in the return statement?
That code never touches the numb variable you define on line 1 after that line.
The function has a locally scoped variable, also called numb, declared in the arguments list which masks it.
None of the code you've provided modifies any variable. The function (which you don't call in your example) just returns a value that has 1 added to the value that was passed to it.
I am trying to create a function which will dynamically set the value of whatever global variable is passed as a parameter. It's not working, and I'm trying to figure out why. Can someone please explain why this doesn't work:
var things = 5;
function setup(variable) {
variable = 7;
}
setup(things);
console.log(things); //should return 7. returns 5 instead. the function had no effect on the global variable
and this also doesn't work:
var things = 5;
function setup(variable) {
window.variable = 7;
}
setup(things);
console.log(things); //should return 7, but returns 5. still not accessing the global variable.
but this does:
var things = 5;
function setup(variable) {
window[variable] = 7;
}
setup("things");
console.log(things); //returns 7
I suspect that what is happening is that the parameter variable is being set as a local variable inside of the function, so any changes are only happening to the local version. But this seems strange because the parameter that's been passed is a global variable. Can someone explain to me what is happening and how to better write this code? Does this require a method (which can then use this to access the original object)?
Thanks!!
Javascript is pass-by-value. (Objects, arrays, and other non-primitives are passed by value-of-reference.) That means that the value of the variable (or reference) is passed to the function, but the function parameter does not become an alias for the actual argument. Thus, you cannot change a variable outside a function without referencing it (as you do in your last example).
See this answer in another thread for more information.
Inside of functions are "variable environments". When the function setup is declared, and the parameter variable set, it creates a local variable in setup's variable environment for variable (the parameter).
So that is why this assignment
function setup(variable) {
variable = 7;
}
Will never change the value sent to variable.
Variables in JavaScript are values. As the variable is passed around, the only thing passed is the value of the variable. However, the value of the variable is assigned to the parameter (again poorly named in this example) variable. When the value of the parameter is assigned to 7, that only changes the local variable, and not the value of the passed variable.
//the value of things is 5
var things = 5;
//the passed value 5 is assigned to variable
function setup(variable) {
//the value of variable is changed to 7 (and nothing is done with 5)
variable = 7;
}
//the value of things is sent to setup
setup(things);
Hopefully this will be a little more enlightening. Consider a situation where setup was actually modifying the value of variable. A good example is when the value has state, such as an array or an object.
//the value of things this time is an object
var things = {};
//the passed value of object is assigned to variable
function setup(variable){
//the value of variable (the object) has a property added named msg with a value of "hello world"
variable.msg = "hello world";
}
//the value of things (an object) is sent to setup
setup(things);
alert(things.msg);//hello world
When variables are passed as arguments to functions, a copy of their value is made and assigned to the name of the argument in the function.
For example:
function foo(a) {
a = 7; // sets the temporary variable(argument) a to 7
}
var bar = 24;
foo(bar); // copies bar's value and passes in the copy to foo
For a function to modify a variable itself, you would have to access it another way. In other languages there are things called pointers that point to a place in memory. This allows you to modify variables directly, as you have where they are located - you can simulate this with JavaScript:
var spam = 3;
var memory = ["bar", 29, "x", foo, false];
function foo(a) {
memory[a] = 7;
}
foo(3);
The above example sets an array called memory and fills it with random gibberish. Then, a function named foo is created that allows for the modification of elements in this memory array.
In my attempt to understand a very specific aspect of closure in javascript, I felt compelled to illustrate it with an example. This is pulled from MDN's explanation of closure:
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
And this example is touched upon here, but I don't think it resolves my own personal confusion, although my confusion is also related to the value of y.
My question is when add5(2) returns function(y), how does it determine the value of y when y is not explicitly assigned anywhere within or outside of makeAdder(x)? Also, is add5(2) = makeAdder(5)(2)? And if so, how can this function execute when makeAdder(x)(y) is not defined in this example? Also, is there a way that describing it as such might help clarify this issue for someone who's having a hard time internalizing the logic behind closure? It appears as if add5(2) assigns 2 to y, but there's no clear way for me to trace this. Any help is much appreciated. Thank you!
One way to look at this is that
var add5 = makeAdder(5);
var add10 = makeAdder(10);
is essentially equivalent to
var add5 = function(y) {
return 5 + y;
}
var add10 = function(y) {
return 10 + y;
}
Perhaps this helps?
The variable "y" is the parameter of the function returned by a call to "makeAdder". It's value is not set in "makeAdder" because that wouldn't make sense; the whole point is to create a new function that will add a given value ("x") to a parameter ("y").
The returned function takes one argument, "y". When, after calling "makeAdder", code calls the function returned and so passes in a value for "y", the final addition (5 + 2 or whatever) is carried out.
Function call syntax (the parenthesized argument list) is evaluated left-to-right, so
makeAdder(5)(2)
is the same as
(makeAdder(5))(2)
meaning,
call the 'makeAdder' function with the parameter 5, and then when that returns treat its return value as a function reference and call that function with the parameter 2.
My question is when add5(2) returns function(y), how does it determine the value of y when y is not explicitly assigned anywhere within or outside of makeAdder(x)?
The function returned by makeAdder is:
function(y) {
return x + y;
}
where x has already been assigned the value 5.
So there is your y. It's inclusion as a formal parameter in the function expression is effectively the same as declaring it with var, x is initialised the same way in makeAdder.
Also, is add5(2) = makeAdder(5)(2)?
Yes, though I think you meant == (equals), not = (assignment).
And if so, how can this function execute when makeAdder(x)(y) is not defined in this example?
makeAdder returns a function, so the second set of parenthesis causes it to be called with whatever value is provided (including none):
makeAdder(5)(2) // 7
is the same as:
var foo = makeAdder(5);
var bar = foo(2);
the only difference being that in the second case, the intermediate result is stored as foo before being called.
Also, is there a way that describing it as such might help clarify this issue for someone who's having a hard time internalizing the logic behind closure?
The real power of a closure is that a function can return another function that continues to have the same scope chain it had when it was created, so that it has exclusive access to local variables of all the execution contexts on its scope chain (other than global variables, they aren't exclusive) after those functions have finished executing. Complex inheritance structures can be created with closures (not recommended though).
It's this persistence that makes a closures really useful, and not just scope chain resolution.
function makeIncreaseByFunction(increaseByAmount) {
return function (numberToIncrease) {
return numberToIncrease + increaseByAmount;
};
}
makeIncreaseByFunction(3)(10);
Updated for Clarity
Can somebody explain why the (3)(10) is written the way it is? I understand that 10 is being supplied as an argument to the inner function, but why is syntactically notated like this? If we had three nested functions, would the arguments always be written in order as in (3)(10)(20)?
With intermediate variable:
var increaseBy3 = makeIncreaseByFunction(3);
var foo = increaseBy3(10);
Without intermediate variable:
var foo = makeIncreaseByFunction(3)(10);
In both cases, the first invokation passes the argument 3 to makeIncreaseByFunction, and as a result it returns the inner function that has closed over increaseByAmount with the value of 3. Whether you create a variable for the intermediate function returned by makeIncreaseByFunction, or just invoke it directly, it does the same thing.
Can you explain a little bit more detail about how in var foo = makeIncreaseByFunction(3)(10); the 10 is getting to the inner function? It just looks syntactically different from how arguments usually get passed in Javascript to me. – ggg
makeIncreaseByFunction(3) returns a function, specifically the "inner function" defined inside makeIncreaseByFunction. As will all functions, you call it with the function ( arguments ) syntax. You can write it like this if it makes more sense to you this way:
( makeIncreaseByFunction(3) )(10)
What happens here is makeIncreaseByFunction(3) gets called first and returns the ⟪inner function⟫, and then we call ⟪inner function⟫(10).
If you were evaluating this by hand (I think this is what you meant by "syntactically"), you could think of it happening step-by-step like this:
// Original invocation
var foo = makeIncreaseByFunction(3)(10);
// Substitute the definition of makeIncreaseByFunction
var foo = (function (increaseByAmount) {
return function (numberToIncrease) {
return numberToIncrease + increaseByAmount;
};
})(3)(10);
// Apply the parameter 3
var foo = (function (numberToIncrease) {
return numberToIncrease + 3;
})(10);
// Apply the parameter 10
var foo = 10 + 3;
// Final result
var foo = 13;
Note: If you want to be technical, all we're doing here is two Beta reductions—but unless you have background with the Lambda Calculus that will probably confuse you more than it will help you!
makeIncreaseByFunction(3) would return function so the syntax for then calling it with 10 would be makeIncreaseByFunction(3)(10).
This is easy to understand as if you have a function foo (imagine that the return of makeIncreaseByFunction(3) is such a function, they are evaluated identically), you would then call it with 10 using foo(10).
As for how the value of 10 is being 'passed', this is the wrong way to thing about things.
You must realise that in Javascript functions are first class objects.
Instead of passing the value to the inner function, you are creating a function that does what you want and then calling it with the outer argument.
It is the same as using a variable to add within a function in a non-functional language except functions can be dynamically created at runtime and the values of any variable in their definition can be set influencing their internal consistency.
The closure refers to the fact that the created function is a black-box which hides the variable used to initialize it, despite still using that variable to increment the value it is called with.
var increaseBy3 = makeIncreaseByFunction(3); is the exact same as (disregarding the local storage for the variable increaseByAmount):
var increaseBy3 = function (numberToIncrease) {
return numberToIncrease + 3;
};
So of course now you can call increaseBy3(10) and get 13. increaseBy3 just references as anonymous function which returns its first argument plus 3.
I already know how to make this code work, but my question is more about why does it work like this, as well as am I doing stuff right.
The simplest example I can make to showcase my issue is this :
Lets say I have a function that increments the value of an input field by 10 on the press of a button.
var scopeTest = {
parseValue : function( element, value ) {
value = parseInt( element.val(), 10 );
//Why does this not return the value?
return value;
},
incrementValue : function( element, button, value ) {
button.on('mousedown', function (e) {
//Execute the parseValue function and get the value
scopeTest.parseValue( element, value );
//Use the parsed value
element.val( value + 10 );
e.preventDefault();
});
},
init : function () {
var element = $('#test-input'),
button = $('#test-button'),
value = '';
this.incrementValue( element, button, value );
}
};
scopeTest.init();
The above code doesnt work because the parseValue method doesn't properly return the value var when executed inside the incrementValue method.
To solve it apparently I have to set the scopeTest.parseValue( element, value ); parameter to the value variable like this:
value = scopeTest.parseValue( element, value );
Than the code works.
But my question is why? Why is this extra variable assignment step necessary, why the return statement is not enough? Also I am doing everything right with my functions/methods, or is this just the way JavaScript works?
Working example here => http://jsfiddle.net/Husar/zfh9Q/11/
Because the value parameter to parseValue is just a reference. Yes, you can change the object, because you have a reference, but if you assign to the reference it now points at a different object.
The original version is unchanged. Yes, the return was "enough", but you saved the new object in a variable with a lifetime that ended at the next line of code.
People say that JavaScript passes objects by reference, but taking this too literally can be confusing. All object handles in JavaScript are references. This reference is not itself passed by reference, that is, you don't get a double-indirect pointer. So, you can change the object itself through a formal parameter but you cannot change the call site's reference itself.
This is mostly a scope issue. The pass-by-* issue is strange to discuss because the sender variable and the called functions variable have the same name. I'll try anyway.
A variable has a scope in which it is visible. You can see it as a place to store something in. This scope is defined by the location of your function. Meaning where it is in your source code (in the global scope or inside a function scope). It is defined when you write the source code not how you call functions afterwards.
Scopes can nest. In your example there are four scopes. The global scope and each function has a scope. The scopes of your functions all have the global scope as a parent scope. Parent scope means that whenever you try to access a name/variable it is searched first in the function scope and if it isn't found the search proceeds to the parent scope until the name/variable is found or the global scope has been reached (in that case you get an error that it can't be found).
It is allowed to define the same name multiple times. I think that is the source of your confusion. The name "value" for your eyes is always the same but it exists three times in your script. Each function has defined it: parseValue and incrementValue as parameter and init as local var. This effect is called shadowing. It means that all variables with name 'value' are always there but if you lookup the name one is found earlier thus making the other invisible/shadowed.
In this case "value" is treated similar in all three functions because the scope of a local var and a parameter is the same. It means that as soon as you enter one of the methods you enter the function scope. By entering the scope the name "value" is added to the scope chain and will be found first while executing the function. And the opposite is true. If the function scope is left the "value" is removed from the scope chain and gets invisible and discarded.
It is very confusing here because you call a function that takes a parameter "value" with something that has the name "value" and still they mean different things. Being different there is a need to pass the value from one "value" to the other. What happens is that the value of the outer "value" is copied to the inner "value". That what is meant with pass-by-value. The value being copied can be a reference to an object which is what most people make believe it is pass-by-reference. I'm sorry if that sounds confusing but there is too much value naming in here.
The value is copied from the outer function to the called function and lives therefor only inside the called function. If the function ends every change you did to it will be discarded. The only possibility is the return your "side effect". It means your work will be copied back to a variable shortly before the function gets discarded
To other alternative is indeed leaving of parameters and work with the scope chain, e.g. the global scope. But I strongly advize you not to do that. It seems to be easy to use but it produces a lot of subtle errors which will make your life much harder. The best thing to do is to make sure variables have the most narrow scope (where they are used) and pass the values per function parameters and return values.
This isn't a scoping issue, it's a confusion between pass-by-reference and pass-by-value.
In JavaScript, all numbers are passed by value, meaning this:
var value = 10;
scopeTest.parseValue( element, value );
// value still == 10
Objects, and arrays are passed by reference, meaning:
function foo( obj ){
obj.val = 20;
}
var value = { val: 10 }
foo( value );
// value.val == 20;
As others have said it's a pass-by-ref vs pass-by-val.
Given: function foo (){return 3+10;} foo();
What happens? The operation is performed, but you're not setting that value anywhere.
Whereas: result = foo();
The operation performs but you've stored that value for future use.
It is slightly a matter of scope
var param = 0;
function foo( param ) {
param = 1;
}
foo(param);
console.log(param); // still retains value of 0
Why?
There is a param that is global, but inside the function the name of the argument is called param, so the function isn't going to use the global. Instead param only applies the local instance (this.param). Which, is completely different if you did this:
var param = 0;
function foo() { // notice no variable
param = 1; // references global
}
foo(param);
console.log(param); // new value of 1
Here there is no local variable called param, so it uses the global.
You may have a look at it.
http://snook.ca/archives/javascript/javascript_pass