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。
相关文章
相关标签/搜索