Home  >  Article  >  Web Front-end  >  JS Core Series: A brief discussion on the scope of functions

JS Core Series: A brief discussion on the scope of functions

大家讲道理
大家讲道理Original
2017-01-24 11:34:01951browse

1. Scope

The so-called scope is: variables are defined in the function body in which they are declared and any function body in which this function body is nested.

function scope(){
    var foo = "global";
    if(window.getComputedStyle){
        var a = "I'm if";
        console.log("if:"+foo); //if:global
    }
    while(1){
        var b = "I'm while";
        console.log("while:"+foo);//while:global
        break;
    }
    !function (){
        var c = "I'm function";
        console.log("function:"+foo);//function:global
    }();
    console.log(
         foo,//global
         a, // I'm if
         b, // I'm while
         c  // c is not defined
    );
}
scope();

(1) The foo variable defined in the scope function, in addition to being accessible by itself, can also be accessed in if statements, while statements and embedded anonymous functions. Therefore, the scope of foo is the scope function body.

(2)In JavaScript, if, while, for and other code blocks cannot form independent scopes. Therefore, there is no block-level scope in JavaScript, only function scope.

However, there is a special case in JS:

If a variable is not declared using var, window will have this attribute, so The scope of this variable does not belong to a certain function body, but to the window object.

function varscope(){
    foo = "I'm in function";
    console.log(foo);//I'm in function
}
varscope();
console.log(window.foo); //I'm in function

2. Scope chain (scope chain)

## The so-called scope chain is: a There are multiple layers of function bodies nested in the function body, and the same variable is defined in different function bodies. When one of the functions accesses this variable, a scope chain will be formed.

foo = "window";
function first(){
    var foo = "first";
    function second(){
       var foo = "second";
       console.log(foo);
    }
    function third(){
       console.log(foo);
    }
    second(); //second
    third();  //first
}
first();

ond, the JS engine will place the scope of second at the head of the linked list, followed by the scope of first, and finally the window object, so the following scope chain will be formed:

second->first->window, at this time, the JS engine searches for the variable foo along the scope chain, and finds "second"

When third is executed, the scope chain formed by third: third->first->window, so what is found is: "frist"

Special case: with statement

The with statement in JS is mainly used for coming When extending the scope chain, the objects in the statement are added to the head of the scope. After the with statement ends, the scope chain returns to normal.

foo = "window";
function first(){
    var foo = "first";
    function second(){
       var foo = "second";
       console.log(foo);
    }
    function third(obj){
       console.log(foo); //first
       with (obj){
           console.log(foo); //obj
       }
       console.log(foo); //first
    }
    var obj = {foo:'obj'};
    third(obj);
}
first();

When executing third(), an obj object is passed, and obj has the attribute foo. When executing the with statement, the JS engine places obj at the head of the original linked list, thus forming a scope The chain is as follows:

obj->third->first->window. The foo found at this time is the foo in obj, so the output is: "obj", and before and after with , are searched along the original linked list, which shows that after the with statement ends, the scope chain has returned to normal.

3. this keyword

In a function, this It always points to the owner object of the current function. this can only determine its specific pointing and its calling object at runtime.

This sentence summarizes everything about this, remember, remember, remember! (ps: Say important things three times!)

window.name = "window";
function f(){
    console.log(this.name);
}
f();//window

var obj = {name:'obj'};
f.call(obj); //obj

When f() is executed, the caller of f() is the window object, so the output of "window"

f.call(obj) is to put f() in the obj object Executed on, it is equivalent to obj.f(). At this time, this in f is obj, so the output is "obj"

## 4. Practical Applicationcode1:

var foo = "window";
var obj = {
    foo : "obj",
    getFoo : function(){
        return function(){
            return this.foo;
        };
    }
};
var f = obj.getFoo();
f(); //window

code2:

var foo = "window";
var obj = {
    foo : "obj",
    getFoo : function(){
        var that = this;
        return function(){
            return that.foo;
        };
    }
};
var f = obj.getFoo();
f(); //obj

code1 and code2 are the best summary of this and scope. If for If you have any doubts about the running results, please discuss!

Code analysis:

code1:
执行var  f = obj.getFoo()返回的是一个匿名函数,相当于:
var f = function(){
     return this.foo;
}
f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window" 

code2:
执行var f = obj.getFoo() 同样返回匿名函数,即:
var f = function(){
     return that.foo;
}
唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回"obj"

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn