javascript series --javascript depth understanding - the scope, the scope chain, the closure face questions Solutions

I. Summary

Js scopes and scope chain is a very important characteristic, related to understand the whole system js, closure is an extension of scope, it has characteristics other languages ​​closure.

What is the scope? It refers to the scope of a variable scope and function.

1, all variables declared within a function in js function in the body is always visible;

2, it has global scope and ES6 are local in scope, but there is no block-level scope (the catch only take effect in the interior thereof);

3, the priority is higher than the local variable global variables.

Second, the scope

We give you a few chestnuts:

2.1 Variable upgrade

var scope="global";
function scopeTest(){
    console.log(scope);
    var scope="local"  
}
scopeTest(); //undefined
复制代码

The above code output is undefined, since the scope variables to enhance the local variables, equivalent to the following

var scope="global";
function scopeTest(){
    var scope;
    console.log(scope);
    scope="local"  
}
scopeTest(); //undefined
复制代码

Note that if you forget to var in the local scope, then the variable is declared as global variables.

var scope="global";
function scopeTest(){
    console.log(scope);
    scope="local"  
}
scopeTest(); //global
var scope="global";
function scopeTest(){
    scope="local" 
    console.log(scope);
}
scopeTest(); //local
复制代码

2.2 does not block-level scope

And our other popular languages ​​are different, js no block-level scope

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();	// 3
data[1]();	// 3
data[2]();	// 3
复制代码

2.3 Scope chain

Each function has its own execution context, when the code is executed in this environment you will create scope chain variable objects,

What is the scope chain? Scope chain is a list of objects.

The role of the scope chain? He assured the orderly access to variable objects.

Local scope chain begins: the current variable object code execution environment, often referred to as "active objects" (AO), find the variable will begin from the first chain of the object, if the object contains variable properties, then stop the search, if there is no scope will continue to look to their superiors, until you find the global object, if not found will be reported ReferenceError.

Closure 2.4

function createClosure(){
    var name = "jack";
    return {
        setStr:function(){
            name = "rose";
        },
        getStr:function(){
            return name + ":hello";
        }
    }
}
var builder = new createClosure();
builder.setStr();
console.log(builder.getStr()); //rose:hello
复制代码

Go back on top in the function of the two closures, the two closures maintained with reference to an external scope, so no matter where calls are able to access the external function variables. In the function a function defined inside, the closure consisting of a function of the external object will be added to its scope, attributes can be accessed through the internal function of the external function, which is a way to simulate js private variables.

Note: Due to the scope of function incidental Closures additional (internal anonymous function scope to carry an external function), therefore, the closure will take up more memory space than some other functions, excessive use can lead to increased memory footprint.

Third, the closure face questions unpacking

Due to the scope chain mechanism, a closure can only win the final value of the internal function, which causes a side effect, if an internal function in a loop, then the value of the variable value is always the last one.

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();	// 3
data[1]();	// 3
data[2]();	// 3
复制代码

If you want to force the return of overdue result, how the whole?

Method One: execute the function immediately

for (var i = 0; i < 3; i++) {
    (function(num) {
        setTimeout(function() {
            console.log(num);
        }, 1000);
    })(i);
}
// 0
// 1
// 2
复制代码

Method Two: returns an anonymous function assignment

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = (function (num) {
      return function(){
          console.log(num);
      }
  })(i);
}

data[0]();	// 0
data[1]();	// 1
data[2]();	// 2
复制代码

Whether the function is executed immediately or return an anonymous function assignment, because the principle of variable passed by value, so will the value of the variable i is assigned to the argument num, inside the anonymous function is used to access and create a num anonymous function, so that each function has a num copies of each other.

Method three: let's use es6

var data = [];

for (let i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();
data[1]();
data[2]();
复制代码

Explain principle:

var data = []; // create an array Data;

// enter the first cycle {let i = 0; // NOTE: let such as use as a loop for the block-level scope // let i = 0 in this field action block level, rather than the global environment data [0] = function () {console.log (i);};}

循环时,let声明了i,所以整个块是块级作用域,那么data[0]这个函数就成了一个闭包,这里用{}表述,只是希望通过它来说明let存在的时候,这个for循环块是块级作用域,而不是全局作用域。

上面的块级作用域,就像函数作用域一样,寒暑表执行完毕,其中的变量会被销毁,但是因为这个代码块中存在一个闭包,闭包的作用域链中引用着块级作用域,所以在闭包被调用之前,这个块级作用域内部的变量不会被销毁。
复制代码

// enter the second cycle {let i = 1; // because let i = 1 and I = 0 above the let
// different in scope, it will not affect each other data [1] = function () { console.log (i);};} when executing Data . 1 , the process proceeds following the execution environment.

{ let i = 1; data[1] = function(){ console.log(i); }; }

在上面这个执行环境中,它会首先寻找该执行环境中是否存在i,没有找到,就沿着作用域链继续向上找,在其所在的块级作用域执行环境中,找到i=1,于是输出1。



## 四、思考题

代码1:
复制代码

var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f; }

checkscope()(); //local scope

代码2:
复制代码

var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f; }

var foo = checkscope(); foo(); //local scope


## 四、参考

1、https://segmentfault.com/a/1190000000618597

2、https://www.cnblogs.com/zhuzhenwei918/p/6131345.html


【注:我是saucxs,也叫songEagle,松宝写代码,文章首发于sau交流学习社区 https://www.mwcxs.top  ,关注我们每天阅读更多精彩内容】复制代码

Reproduced in: https: //juejin.im/post/5d0341a66fb9a07f0219fcb3

Guess you like

Origin blog.csdn.net/weixin_34149796/article/details/93176511