js之做用域链

js采用的是词法做用域链,在代码书写阶段,做用域链就被定义了,因此 对于新手来讲,要搞读懂js代码,首先就要弄清楚js的做用域链,下面看一份代码数组

function test(a){
            var b = a+2;
            var bar = function(c){
                console.log(a,b,c);
            }
            bar(b*a);
        }
        test(2);

这个函数中 咱们定义了一个test 函数,该函数中咱们能够看出做用域链层层嵌套,首先是全局的,而后是test,而后是bar,在上下文执行栈中,全局执行环境会被放在栈底,而咱们的test函数会第二我的入栈,而后发现里面嵌套了一个bar函数,又会将bar函数入栈浏览器

咱们用一个数组来比做执行上下文栈,那么上面代码能够写成闭包

        var Esc = [];
        Esc.push(gloabContext);//首先全局上下文先压入栈底
        Esc.push(test); //其次是test的执行上下文
        Esc.push(bar);//最后入栈的是bar
        Esc.pop(bar);//而后bar 执行完以后就弹出 变量回收,闭包变量会存在
        Esc.pop(test);// test 弹出
        Esc.pop(gloabContext);// 浏览器或者也页面关闭时 全局执行环境清空

上面就是一个静态做用域的执行流程,也就是说做用域只跟当前函数变量代码声明时有关,下面再看一个例子,函数

var test = "global test";
        function foo(){
            var test = "local test";
            var bar = function(){
                console.log(test);
            }
            bar();
        }
      foo() //输出 localtest

上面输出的是local test ,由于当今入bar的执行上下文的时候,test 会在上一层做用域链foo的执行上下文中找到,也就是在做用域创建阶段,bar函数和test变量会绑定在foo的执行上下文环境中,咱们再看一个例子spa

var value = 1;

function foo() {
    console.log(value);
}

function bar() {
    var value = 2;
    foo();
}

bar();//输出为1

上面的代码,若是按照常规的思惟,咱们就会想到value 会在bar中找到,应该输出2,但这种想法是错的,由于做用域绑定在代码书写的时候就肯定了,也就是说,当foo函数在全局上下文执行环境书写时,就跟全局value一块绑定了,因此看成用域链向上查找的时候code

就会找到全局value,而不是bar中的,因此,js中的做用域链是在书写代码时肯定的,而不是在执行的时候肯定的。blog

咱们再看一到题目,作用域

var test = "global test";
        function foo(){
            var test = "local test";
            var bar = function(){
                console.log(test);
            }
            bar();
        }
      foo()
    var test1 = "global test1";
        function foo1(){
            var test1 = "local test1";
            var bar = function(){
                console.log(test1);
            }
            return bar;
        }
        foo1()();

这两段代码输出是同样的吗,若是同样,那么他们有不一样点吗?io

相关文章
相关标签/搜索