JavaScript的静态作用域

  • JS是静态作用域。比较下面两段代码:
  • 代码一
    function f(){
        alert(x);
    }
    
    function g(){
        var x = 100;
        f();
    }
    
    g()
  • 代码二
    function g(){
        var x =  100;
        function f(){
            alert(x);
        }
        f();
    }
    
    g();
  • 代码一会报错:显示x没有defined;代码二alert:100;
  • 代码一报错原因:函数在创建(声明)的时候首先向内部属性[[scope]]中压入当前的环境指针,代码一的情况两个函数都首先压入window;而在函数执行/调用的时候,则会在[[scope]]顶部压入自己的环境指针,指向自己的活动对象。如此一来,f()的[[scope]]中并没有指向g()的指针,而是直接指向window,而它本身的环境和window并没有为x定义,所以会报错。
  • 代码二:按照上述的原理,f的scope依次指向:f()本身活动对象、g()的活动对象、(g的活动对象又指向)window对象;形成了一条三层的作用域链,而g()执行的时候,内部的f()同样执行,并在g的活动对象中找到x的定义和值,即alert:100;
  • 闭包一般采用函数表达式的方式创建,执行到此语句的时候同时声明并赋值,相当于代码二的情况。因此很容易与外部环境形成作用域链。
    注意到如果用new Function()创建函数,scope[0]会指向window。
  • 代码一,如果在声明一个全局变量:var x = 100,则代码一会alert:100。
posted @ 2017-11-29 09:47  nebulium  阅读(1301)  评论(0编辑  收藏  举报