作用域和作用域链

  作用域

  在Javascript里,作用域有两种:全局作用域和局部作用域

1)全局作用域

全局作用域是最外围的一个执行环境。根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样。在Web浏览器中,全局作用域被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。

举个例子:

var a = 123;
console.log(window.a)  //输出结果为123

  可以说 var a = 123 等价于 window.a,可以通过window.a的方式获取变量a的值

  在全局作用域下,创建的变量是全局变量(global variable),可以在函数内部读取

2)局部作用域

每个函数都有自己的执行环境,在这执行环境就是局部作用域,所以一般也称为函数作用域,而在局部作用域中创建的变量称为局部变量  注意:要用var声明

function abc(){
    var x = 2;
}

  如果在函数里省略了var声明变量,创建的是全局变量,我们要特别注意

  在函数里创建的局部变量(local variable),在函数外是无法读取的,只能在它的区块内使用

  作用域链


var a = 1;
function foo(){
    var b = 2;
    function bar(){
        var c = 3;
        console.log(a+b+c);
    }
    bar();
}
foo()

  这里函数bar运行a+b+c,但是函数里里没有变量b和c,就会从自身往上依次寻找变量,这个搜索机制就是作用域链。这个例子的搜索顺序:bar->foo->window

在Javascript高程中的定义是这样的:

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即 arguments 对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而在下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。

标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标识符为止(如果找不到标识符,通常会导致错误发生)。

简单来说,就是在局部作用域中会先在自身的变量对象中搜索变量和函数名,如果搜索不到则会再上一级寻找,还是搜不到就会再往上上一级,直至搜索到为止,这个过程会延续到全局作用域,全局作用域的变量始终是作用域链中的最后一个对象

猜你喜欢

转载自www.cnblogs.com/ianyanyzx/p/9221876.html