JavaScript lexical scopes and calling objects

Source: Internet
Author: User

The relationship between the function scope, the calling object, and the closure of Javascript is subtle, and there are a lot of articles about them, but I don't know why many novices are hard to understand. I will try to express my own understanding in the more popular language.

Scope scope

A function in Javascript is a lexical scope, which means that the function runs in its scope when it is defined rather than within the scope at which it is executed. This is what the Rhino book says. But when "defined" and "executed (called)" These two things are not clear to some people. Simply put, a function A at "definition" is the function A () {} When the statement executes is defined by the time, and A is called a () when the statement executes. These two concepts must be clearly divided. Jurong e-Mao Steel

What is the lexical scope (hereinafter referred to as "scope", unless specifically specified)? It is an abstract concept, it is a "scope", scope in English is the meaning of the scope. The scope of a function is the "scope" in which it is defined, that is, the "scope" of its outer layer, which contains the variable attributes of the outer layer, which is set to an internal state of the function. When a global function is defined, the "scope" of the global (the outer layer of the function) is set to an internal state of the global function. When a nested function is defined, the "scope" of the nested function (the outer function) is set to an internal state of the nested function. This "internal state" can actually be understood as a scope chain, see below.

According to the above, a function scope is the "scope" in which it is defined, then the function scope in Javascript is determined when the function is defined, so it is a static scope, and the lexical scope is also known as the static scope.

Calling Object Call objects

The calling object of a function is dynamic, and it is instantiated when the function is called. We already know that when a function is defined, its scope chain is determined. When the JAVASCRIPT interpreter invokes a function, it adds a new object (the calling object) to the front of the scope chain. A property of the calling object is initialized to a property called arguments, which references the arguments object of the function, and the arguments object is the actual argument of the function. All local variables declared with the VAR statement are also defined in the calling object. At this point, the calling object is at the head of the scope chain, with local variables, function-form arguments, and Arguments objects all within the scope of the function. This time, of course, local variables, function-form arguments, and Arguments objects overwrite properties with the same name in the scope chain.

Relationships between scopes, scope chains, and call objects

My understanding is that the scope is abstract and the calling object is instantiated.

When a function is defined, it is actually the outer function execution, it determines the scope chain is actually its outer function call object chain, when the function is called, its scope chain is based on the definition of the scope chain (its outer function call object chain) plus an instantiated call object. So the function's scope chain is actually called the object chain. When a function is called, its scope chain (or chain of call objects) is actually a superset of the scope chain that it determines at the time it is defined.

The relationship between them can be expressed as: scope? Scope chain? Call object.

Too much of a mouth, for example:

function f (x) {    var g = function () {return x;}    return g;} var G1 = f (1); alert (G1 ());  Output 1

Suppose we look at the global as a large anonymous function like this:

(function () {    //Here is global scope}) ();

Then the example can be seen as:

(function () {    function f (x) {        var g = function () {return x;}        return g;    }    var G1 = f (1);    Alert (G1 ());  Output 1}) ();
    1. When a global large anonymous function is defined, it has no outer layer, so its scope chain is empty.
    2. The global large anonymous function is executed directly, and there is only one ' global Call object ' in the global scope chain.
    3. The function f is defined when the scope chain of the function f is the scope chain of its outer layer, which is the ' Global Call object '.
    4. The function f (1) is executed, its scope chain is the new F (1) Call object plus the function f is defined when the scope chain, that is, ' F (1) Call Object--Global Call object '.
    5. The function g (which is to be returned to G1, named G1 Bar) is defined in F (1) and its scope chain is the scope chain of its outer function f (1), that is, ' F (1) Call Object--Global Call object '.
    6. function f (1) Returns the definition of function g to G1.
    7. The function G1 is executed, and its scope chain is the new G (1) Call object plus the outer f (1) Scope chain, the ' G1 call Object->f (1) Call Object--Global Call object '.

That's a pretty clear look.

Closed Bag Closuer

A simple argument for closures is that when nested functions are called outside of nested functions, closures are formed.

The previous example is actually a closed packet. G1 is defined inside F (1) and is executed after F (1) is returned. As you can see, one effect of closures is that when the nested function f is returned, its internal resources are not freed. When the G function is called externally, G can access the internal variables of F. Based on this feature, you can write a lot of elegant code.

For example, to make a unified counter on a page, if the closure of the wording, you can write:

var counter  = (function () {    var i = 0;    var Fns = {"Get": function () {return i;},               "inc": function () {return ++i;}};    return FNS;}) ();//do somethingcounter.inc ();//do something Elsecounter.inc (); var c_value = Counter.get ()  ; Now C_value is 2

In this way, a variable i is maintained in memory, and the value of I is not directly manipulated anywhere else in the program, only through the two operations of the counter.

At SetTimeout (FN, delay), we cannot pass arguments to the function handle of FN, but we can bind the required parameters to the FN by means of a closure method.

for (var i=0,delay=1000; i< 5; i++, delay +=1000) {    setTimeout (function () {        console.log (' I: ' + i + "delay:" + D Elay);    }, delay);}

In this way, the printed values are

I:5 delay:6000i:5 delay:6000i:5 delay:6000i:5 delay:6000i:5 delay:6000

Instead of using closures, you can easily bind the parameters you want to pass in:

For (var i=0, delay=1000; i < 5; i++, delay + +) {    (function (A, _delay) {         setTimeout (function () {             consol E.log (' I: ' +a+ ' delay: "+_delay);        }, _delay);    }) (i, delay);}

Output:

i:0 delay:1000i:1 delay:2000i:2 delay:3000i:3 delay:4000i:4 delay:5000

The closure also has a very common place, that is, when binding the callback function of the event. It is also true that a bound function handle cannot be used as a parameter, but it can be bound in the form of a closed packet.

Summarize
    1. The lexical scope and scope chain of a function are different things, lexical scopes are abstract concepts, and scope chains are instantiated call object chains.
    2. When a function is defined, it is also the function of its outer layer when it is executed.
    3. The lexical scope of a function is determined when it is defined, but it is still an abstract concept and cannot be instantiated.
    4. The function defines a thing when it is defined, that is, the scope chain of its outer function, and this is an instantiated thing.
    5. When a function is called multiple times, its scope chain is different.
    6. Closures are powerful. Rhino Book is right, understanding these things, you can call yourself a senior Javascript programmer. Because of these concepts, there are many design patterns that you can play with Javascript.

JavaScript lexical scopes and calling objects

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.