JS Closure and scope

Source: Internet
Author: User

The scope of nesting will form a scope chain, and the nesting of functions will form a closure. Closures and scope chains are one of the important features of JavaScript that distinguishes it from other languages.

Scope

There are two types of scopes in JavaScript: function scope and global scope.

Variables declared in a function and parameters of the function have the same scope, that is, the function scope. An example of a simple function scope:

function foo () {
var bar = 1;
{
var bar = 2;
}
return bar; 2
}

Unlike other block-scoped languages such as C, this will always return 2.

Global scope, which can be understood by the browser as a Window object (node. JS is global):

var bar = 1;
function foo () {}
alert (Window.bar); 1
alert (Window.foo); "Function foo () {}"


For both the variable bar and the function foo belong to the global scope, which is a property of window.

Scope chain

When a variable is accessed in JavaScript, it begins with local variables and parameters, traversing the scope up and down through the global scope.

var scope = 0, zero = "Global-scope";
(function () {
var scope = 1, one = "scope-1";
(function () {
var scope = 2, and both = "scope-2";
(function () {
var scope = 3, three = "scope-3";
Scope-3 scope-2 scope-1 Global-scope
Console.log ([Three, one, one, Zero].join (""));
Console.log (scope); 3
})();
Console.log (typeof three); Undefined
Console.log (scope); 2
})();
Console.log (typeof); Undefined
Console.log (scope); 1
})();
Console.log (typeof one); Undefined
Console.log (scope); 0

In the innermost function, each variable can be traversed and output. In the second-to-last function, the variable three cannot be traversed, so the output is undefined.

As an example of a popular point, when you are ready to spend money on something, you will feel your wallet first, and you can ask your father for it without you, and your father will never find your grandfather again. And when your dad doesn't have the money to buy things, he's not going to come looking for you.

Closed Package

In one function, define another function, called function nesting. The nesting of functions will form a closure.

Closures are complementary to scope chains, and the nesting of functions creates a closure at the same time as multiple scopes of chain relationships.

function bind (func, target) {
return function () {
Func.apply (target, arguments);
};
}


So how do you understand closures?

External functions cannot access inline functions
External functions also cannot access parameters and variables of inline functions
Inline functions can access parameters and variables of external functions
In other words: The inline function contains the scope of the external function
Let's take a look at the example of the scope chain described earlier, this time from a closure perspective:

var scope = 0, zero = "Global-scope";
(function () {
var scope = 1, one = "scope-1";
(function () {
var scope = 2, and both = "scope-2";
(function () {
var scope = 3, three = "scope-3";
Scope-3 scope-2 scope-1 Global-scope
Console.log ([Three, one, one, Zero].join (""));
Console.log (scope); 3
})();
Console.log (typeof three); Undefined
Console.log (scope); 2
})();
Console.log (typeof); Undefined
Console.log (scope); 1
})();
Console.log (typeof one); Undefined
Console.log (scope); 0


The innermost function can access all the variables defined inside and outside of it. The second-to-last function does not have access to the innermost variable, and the innermost scope = 3 Assignment does not have an effect on the variable with the same name outside it.

Another angle to understand closures:

Each time an external function is called, the inline function is created once
When it is created, the scope of the external function (including any local variables, parameters, and so on) becomes part of the internal state of each inline function object, even after the external function has finished executing and exiting
Look at the following example:

var i, list = [];
for (i = 0; i < 2; i + = 1) {
List.push (function () {
Console.log (i);
});
}
List.foreach (function (func) {
Func ();
});

We will get two "2" instead of the expected "1" and "2" because the variable i accessed by the two functions in the list is the same variable in its previous level scope.

We changed the code to use closures to solve this problem:

var i, list = [];
for (i = 0; i < 2; i + = 1) {
List.push ((function (j) {
return function () {
Console.log (j);
};
}) (i));
}
List.foreach (function (func) {
Func ();
});

The outer "immediate execution function" receives a parameter variable I, which exists as a parameter J within its function, and it points to the same reference as the name J in the returned inner function. After the outer function executes and exits, the parameter J (whose value is now the current value of i) becomes part of the state of the inner layer function is preserved.

JS Closure and scope

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.