When i check MDN to learn some points about closures, i faced the below function.
It can be a known pattern in javascript, but it's strange for java or .NET developer.
I want to know how it works, i know about arguments and first class object behavior in javascript language but how add5(2) assigned 2 to y variable.
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
First, any time there are named parameters - there is an implicit variable declaration. So forget the function above, just consider this
var example = function() {
var x = 5;
return function(y) {
return x + y;
}
}
var inner = example();
console.log(inner(5));
> '10'
Do you understand how the above works? if not I'd recommend looking into javascript closure and what it means.
Javascript Closures
In the above function makeAdder, the only difference is that we are passing the value of x. But x is still defined in the outer function, and the resulting returned function closes over its value
The function makeAdder returns a function, so the variables add5 and add10 are just references to functions. When you call those functions with a parameter vale, that ends up as the parameter y in the function.
You can do the same in C# for example, and the closure works the same:
public static Func<int, int> MakeAdder(int x) {
return y => x + y;
}
Using it:
Func<int, int> add5 = MakeAdder(5);
Func<int, int> add10 = MakeAdder(10);
Console.WriteLine(add5(2));
Console.WeiteLine(add10(2));
makeAdder returns a function which can be seen like:
var x = 5;
function add5(y){
return x + y;
}
makeAdder(5) called the function makeAdder, with x bound to 5. This function returns another function. Furthermore, since the value of x was provided, the anonymous function inside makeAdder knows the value of x. At this point in time, makeAdder will return:
function(y) {
return 5 + y;
}
Therefore, by assigning this new function to add5, add5 is now a function, as well. If we call add5(2), it will use the above function, and perform the following:
function(2) {
return 5 + 2;
}
Which will output 7.
How does this work?
The function defined in the closure 'remembers' the environment in
which it was created.
ref
Related
I was just playing with JavaScript and creating constructors, and I came across this perplexing code.
var foo = function(){
this.x = 1;
return function(){
return this.x;
}
}
var x = new foo();
console.log(x);
I executed the following for this:
console.log(x); // The given output is expected for this line of code
console.log(x());
console.log(x()());
console.log(x()()());
All of the above gave me the same output as following:
function (){
return this.x;
}
Can somebody explain what is happening in the above code.
I could not give a proper title for this question. Sorry about that.
Note: I'm aware of constructors in JS. And the above code was just out of curiosity.
To make a long story short - it's not doing anything useful.
If a constructor returns an object, then the value produced by the new expression is that value rather than the constructed object. So instead of getting an instance of foo, you are getting a function that returns this.x.
It looks like this code is trying to produce a function that returns the this.x value of the created object, but that's not what it's doing. Since you are calling x() by itself, this.x is actually referring to the global x variable, so no matter how many times you call x()()(), it just returns itself.
If you used any variable name other than x and did not create an x variable (e.g. y), then y() would just return undefined, and y()() would produce a ReferenceError.
This would also fail much sooner in strict mode, becuase this inside the function would be referring to undefined when you tried to call it.
My interpretation is this:
x contains the result of calling foo().
foo() returns a function:
function(){
return this.x;
}
the body of this function is written to the console
Here is an example to the previous answer, that demonstrates it:
var x = 5;
var foo = function(){
this.x = 1;
return function(){
return this.x;
}
}
var b = new foo();
b() //--> 5
This code is all about function invocation context.
At runtime, the this referenced in this.x = 1; is bound to a different object than the this referenced in return this.x;
x() invokes the anonymous function returned by foo, in a global context. For ECMAScript 3 (and earlier) environment, global context function invocation binds the global object to this, inside the invoked function. Thus, return this.x; refers to var x you define on the global object.
In ECMAScript 5, use strict; statement can be placed in any function declaration to disable the binding of the global object in "this" way.
The anonymous, nested function can access "foo's" this in a closure:
var foo = function(){
this.x = 1;
var that = this;
return function(){
return that.x;
}
}
var x = new foo();
console.log(x); // function(){ ...
x(); // 1
How can I get access to my y() function?
function x() {
function y() {
return 1;
}
}
Is it possible at all?
It is scoped to x, kind of like:
function x() {
var y;
}
So, yes, from within x, and no otherwise.
If you wanted it to be, you could create it as a property on x:
var x = (function () {
function x() {
…
}
function y() {
…
}
x.y = y;
return x;
})();
You mean access it from outside the function x?
That's not possible, the function y doesn't exist when x is not running. It's declared locally inside x so it's only accessible inside x.
To make it accessible outside x you need to expose a reference to it outside the function. If you expose a reference to it, it survives after the function ends. For example:
function x() {
function y() {
return 1;
}
return y;
}
// get the reference to y
var f = x();
// call y
f();
You can get access to your y function inside of the scope of the x function Only.
But you can get access to the y function if you return it from your x function or assign it to a global variable or to the variable that is in scope outside of your x function. This is also know is closure, your y function will keep the reference in memory to the scope it was created in if you pass it around.
function x() {
var anotherNum= 2;
function y() {
return 1 + anotherNum;
}
return y;
}
Now you can get the y function along with the scope it was created in. Notice that it will use anotherNum in the computation as it was created in the x function.
var yFunc = x();
console.log(yFunc()) // will print 3
One way is to return it out of the scope
function x() {
function y() {
return 1;
}
return {
y:y
};
}
Whenever you call x(), it returns an object with the function y as a member
var a = x();
a.y(); //this returns 1
This is similar to the revealing module pattern described here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FClosures
Also good to read up on closures:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FClosures
Consider the following JavaScript code:
function getFunction(x) {
var closureMember = x;
return function() {
return closureMember * 2;
};
}
var f = getFunction(5);
Here a call to getFunction creates a closure containing the member closureMember, returns an anonymous function referencing this closure, and assigns it to the variable f. If I invoke the anonymous function, its code will be executed and the member closureMember in the closure will be actually accessed.
JavaScript allows me to invoke the method toString on an anonymous function that returns the textual representation of its code. In this case, the representation will contain the name of closureMember without giving any access to the actual variable (note that it can exists in multiple instances if getFunction was invoked multiple times).
Question:
Does JavaScript provide any reflection capabilities that would allow to analyze/modify the structure and content of closures associated with function instances at runtime?
I'm not sure that it's exactly what you want but the next code works fine.
function getFunction(x) {
var closureMember = x;
return function() {
return closureMember * 2;
};
}
function changeClosure(x, closure){
var closureMember = x;
return eval("(" + closure.toString() + ")");
}
var f = getFunction(5);
var g = changeClosure(42, f);
g();
I just started reading Functional JavaScript and immediately was introduced to a function that I don't understand:
function splat(fun) {
return function(array) {
return fun.apply(null, array);
};
}
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements([1, 2]);
//=> 3
How does splat(function(x, y) { return x + y }) work. It's called with the array [1,2], but it seems like the anonymous function inside the call to splat takes two parameters, not one array.
Putting console.log(fun) on line 2 of this code shows that fun is the entirety of the anonymous function(x, y) { return x + y }. console.log(array) after return function(array) { shows that array is [1, 2]. Where does array come from then?
Thanks much.
It might be simpler to see how this function would have been written without using the .apply method:
function splat(fun) {
return function(array) {
return fun(array[0], array[1]);
};
}
First you call splat, passing it a function:
var add = function(x,y){ return x + 1 };
var ff = splat(add);
At this point, ff refers to the function(array) function, meaning its an one-argument function. The private variable fun refers to the add function.
Now, you call ff passing its one argument
ff([1,2]);
and it uses the values in the array to call fun with two arguments
return fun(array[0], array[1]);
The only difference between this and the real example is that the apply method lets you work with any argument array length instead of hardcoding a specific length (2) like I did.
//Every time we call this function, we get another one back
function splat(fun) {
return function(array) { // <-- this one will be returned in splat();
return fun.apply(null, array);
};
}
//Step one, call splat, pass a function as parameter
var addArrayElements = splat(function(x, y) { return x + y });
/*
Get back a function that accepts an array, and will execute the function we just passed in on it
*/
// This will call the newly created function, func will be available because it's in a closure
addArrayElements([1, 2]);
The last thing is that, even if the anonymous function takes two parameters, we call apply on it so it will bind array[0] ==> x and array[1] ==> y
This is an example of a higher order function. That's a function that takes functions as arguments and returns functions instead of just regular values (though functions are "just regular values" in Javascript). In this case:
function splat(fun) {
splat takes a function as its argument...
return function(array) {
...and returns a new function which takes an array...
return fun.apply(null, array);
...and when called calls the first fun function with the array .applied as its arguments.
So splat takes one function which expects several parameters and wraps it in a function which takes an array of parameters instead. The name "splat" comes from languages like Ruby, where a * (a "splat" or "squashed bug") in the parameter list of a function accumulates an arbitrary number of arguments into an array.
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements is now basically:
function (array) {
// closed over variable:
// var fun = function(x, y) { return x + y }
return fun.apply(null, array);
}
Here this is realized by a closure, which closes over and "preserves" the original fun passed to splat in the new returned function.
addArrayElements = function(array) { fun.apply(null, array); };
BUT
it has a closure whereby the variable context of its containing scope (that of the splat function that created the anonymous function) remains visible and accessible.
In JavaScript, functions are first-class objects that can be referenced and passed as arguments or, as in this case, through the closure mechanism.
Edit: about JavaScript and scope
In most languages, variables are, by default, local to the scope they're defined in (which usually is a function's local symbol table). By contrast, in JavaScript a variable is local only if it is defined using the var keyword; otherwise, the symbol will be looked back in the chain of the containing scopes, up to the implicit root object (which in the case of web browsers is window. I.e.,
function foo() { someVar = "bar"; }
foo();
alert(someVar); // shows "bar"
Not being restricted to the local scope, the symbol has been (purposely or not) leaked to the root scope.
Taking it one step further:
function foo() {
var baz = function() {
someVar = "bar";
};
baz();
}
foo();
alert(someVar); // shows "bar"
However, if you declare someVar within foo:
function foo() {
var someVar;
var baz = function() {
someVar = "bar";
};
baz();
alert("someVar in foo=" + someVar); // shows "bar"
}
foo();
alert("someVar in root=" + window.someVar); // shows "undefined"
Note that in this last version I needed to use window.someVar instead of just someVar because someVar never got defined as a variable in the root scope nor as a property of the root object, which caused an error.
a more functional approach uses bind(), which is short enough you don't really need splat anymore, and it's always nice to eliminate closures:
var addArrayElements = Function.apply.bind( function(x, y) { return x + y } , null );
addArrayElements([1, 2]); // === 3
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
What's the difference between:
function sum(x, y) {
return x+y;
}
// and
var sum = function (x, y) {
return x+y;
}
Why is one used over the other?
The first is known as a named function where the second is known as an anonymous function.
The key practical difference is in when you can use the sum function. For example:-
var z = sum(2, 3);
function sum(x, y) {
return x+y;
}
z is assigned 5 whereas this:-
var z = sum(2, 3);
var sum = function(x, y) {
return x+y;
}
Will fail since at the time the first line has executed the variable sum has not yet been assigned the function.
Named functions are parsed and assigned to their names before execution begins which is why a named function can be utilized in code that precedes its definition.
Variables assigned a function by code can clearly only be used as function once execution has proceeded past the assignment.
The first tends to be used for a few reasons:
The name "sum" shows up in the
stacktrace which makes debugging
easier in many browsers.
The name
"sum" can be used inside the
function body which makes it easier
to use for recursive functions.
function declarations are "hoisted"
in javascript, so in the first case,
the function is guaranteed to be
defined exactly once.
Semicolon insertion causes
var f = function (x) { return 4; }
(f)
to assign 4 to f.
There are a few caveats to keep in mind though.
Do not do
var sum = function sum(x, y) { ... };
on IE 6 since it will result in two function objects being created. Especially confusing if you do
var sum = function mySym(x, y) { ... };
According to the standard,
function sum(x, y) { ... }
cannot appear inside an if block or a loop body, so different interpreters will treat
if (0) {
function foo() { return 1; }
} else {
function foo() { return 2; }
}
return foo();
differently.
In this case, you should do
var foo;
if (0) {
foo = function () { return 1; }
} ...
The first one is a named function statement, the second one assigns an anonymous function expression to a variable.
The function statement is added to its scope immediately - you don't need to run it before being able to call it, so this works:
var y = sum(1, 2);
function sum(x, y) {
return x + y;
}
But the function expression is only assigned to the variable when the code is executed, so this doesn't work:
// Error here because the function hasn't been assigned to sum yet.
var y = sum(1, 2);
var sum = function(x, y) {
return x + y;
}
An advantage of the expression form is that you can use it to assign different functions to the expression at different points - so you can change the function, or use a different one under different conditions (such as depending on the browser being used).
An advantage of a named function statement, is that debuggers will be able to display the name. Although, you can name function expressions:
var sum = function sum(x, y) {
return x + y;
}
But this can be confusing since the two names are actually in different scopes and refer to different things.
The two code snippets you've posted there will, for almost all purposes, behave the same way.
However, the difference in behaviour is that with the second variant, that function can only be called after that point in the code.
With the first variant, the function is available to code that runs above where the function is declared.
This is because with the second variant, the function is assigned to the variable foo at run time. In the first, the function is assigned to that identifier foo at parse time.
More technical info
Javascript has three ways of defining functions.
Your first example is a function declaration. This uses the "function" statement to create a function. The function is made available at parse time and can be called anywhere in that scope. You can still store it in a variable or object property later.
Your second snippet shows a function expression. This involves using the "function" operator to create a function - the result of that operator can be stored in any variable or object property. The function expression is powerful that way. The function expression is often called an "anonymous function" because it does not have to have a name,
The third way of defining a function is the "Function()" constructor, which is not shown in your original post. It's not recommended to use this as it works the same way as eval(), which has its problems.
The difference is...
This is a nameless function
var sum = function (x, y) {
return x+y;
}
So if you alert(sum); you get "function (x, y) { return x + y; }" (nameless)
While this is a named function:
function sum(x, y) {
return x+y;
}
If you alert(sum); now you get "function sum(x, y) { return x + y; }" (name is sum)
Having named functions help if you are using a profiler because the profiler can tell you function sum's execution time...etcetera instead of an unknown functions's execution time...etcetera
here's an other example:
function sayHello(name) { alert('hello' + name) }
now,suppose you want modify onclick event of a button, such as it says "hello world"
you can not write:
yourBtn.onclik = sayHello('world'), because you must provide a function reference.
then you can use second form:
yourBtn.onclick = function() { sayHello('workld'); }
Ps: sorry for my bad english!
They mean the exact same thing. It's just syntactic sugar. The latter is IMO more revealing of what JavaScript is really doing; i.e. "sum" is just a variable, initialised with a function object, which can then be replaced by something else:
$ js
js> function sum(x,y) { return x+y; }
js> sum(1,2);
3
js> sum=3
3
js> sum(1,2);
typein:4: TypeError: sum is not a function
js> sum
3