美文网首页
JS作用域链

JS作用域链

作者: zooeydotmango | 来源:发表于2019-08-21 01:47 被阅读0次

一、作用域

在JavaScript中,变量的作用域有全局作用域和局部作用域两种,局部作用域又称为函数作用域。

  • 全局作用域
    在代码中任何地方都能访问到的对象拥有全局作用域
  • 局部作用域(函数作用域)
    局部作用域在函数内创建,在函数内可访问,函数外不可访问

二、作用域链

了解作用域链之前我们要知道一下几个概念:

变量和函数的声明
函数的生命周期
Activetion Object(AO)、Variable Object(VO)

变量和函数的声明

在JavaScript引擎解析JavaScript代码的时候,首先,JavaScript引擎会把变量和函数的声明提前进行预解析,然后再去执行其他代码,也就是变量提升和函数提升。函数命名法实际上是变量提升,赋值内容还是在原位。
如果变量名和函数名声明时相同,函数优先声明

什么是AO、VO

英文解释:
AO:Activetion Object(活动对象)
VO:Variable Object(变量对象)

VO对应的是函数创建阶段,JS解析引擎进行预解析时,所有的变量和函数的声明,统称为Variable Object。该变量与执行上下文相关,知道自己的数据存储在哪里,并且知道如何访问。VO是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:

变量 (var, 变量声明);
函数声明 (FunctionDeclaration, 缩写为FD);
函数的形参

举个例子:

function add(a,b){
    var sum = a + b;
    function say(){
        alert(sum);
    }
    return sum;
}
// sum,say,a,b 组合的对象就是VO,不过该对象的值基本上都是undefined

AO对应的是函数执行阶段,当函数被调用执行时,会建立一个执行上下文,该执行上下文包含了函数所需的所有变量,该变量共同组成了一个新的对象就是Activetion Object。该对象包含了:

函数的所有局部变量
函数的所有命名参数
函数的参数集合
函数的this指向

举个例子:

unction add(a,b){
    var sum = a + b;
    function say(){
        alert(sum);
    }
    return sum;
}

add(4,5);
//  我用JS对象来表示AO
//  AO = {
//      this : window,
//      arguments : [4,5],
//      a : 4,
//      b : 5,
//      say : ,
//      sum : undefined
//  }

JavaScript作用域链

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)来保证对执行环境有权访问的变量和函数的有序访问。作用域第一个对象始终是当前执行代码所在环境的变量对象(VO)

function add(a,b){
    var sum = a + b;
    return sum;
}

假设函数是在全局作用域中创建的,在函数a创建的时候,它的作用域链填入全局对象,全局对象中有所有全局变量,此时的全局变量就是VO。此时的作用域链就是:

此时作用域链(Scope Chain)只有一级,就为Global Object

    scope(add) -> Global Object(VO)
    
    VO = {
        this : window,
        add : 
    }

如果是函数执行阶段,那么将其activation object(AO)作为作用域链第一个对象,第二个对象是上级函数的执行上下文AO,下一个对象依次类推。

add(4,5);

例如,调用add后的作用域链是:

此时作用域链(Scope Chain)有两级,第一级为AO,然后Global Object(VO)

    scope(add) -> AO -> VO

    AO = {
        this : window,
        arguments : [4,5],
        a : 4,
        b : 5,
        sum : undefined
    }
    
    VO = {
        this : window,
        add : 
    }

在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程,从第一个对象开始,逐级向后回溯,直到找到同名标识符为止,找到后不再继续遍历,找不到就报错

因此我们在实际使用时可以从函数开始找起,逐级向上一层作用域寻找变量

相关文章

  • 干货!月薪80k前端大佬面试笔记:JS闭包解析!

    三点注意事项 JS没有块级作用域,只有全局作用域和局部作用域(函数作用域)。 JS中的作用域链,内部的作用域可以访...

  • JS 作用域链、导入导出

    1. JS 的作用域链 作用域在 JS 中表示变量的可访问性和可见性。JS 作用域有 3 种:1. 全局作用域;2...

  • 闭包

    一、理解闭包前js基础1、作用域链(作用域、作用域链中有说)。2、js的内存回收机制。一个函数在执行开始的时候,会...

  • 作用域和作用链

    关键词:作用域作用链 作用域 js中没有块级作用域 全局作用域,函数作用域太简单,就不演示(≧▽≦)/啦啦啦 作用...

  • 2018-12-18

    JS高级 作用域&作用域链 作用域: 1.作用域的个数:n(函数声明的个数)+1(全局作用域)2.作用域不会存储变...

  • 浅谈JS作用域链

    浅谈JS作用域链 作用域 作用域(scope)就是变量访问规则的有效范围。作用域外,无法引用作用域内的变量;离开作...

  • JS博客

    JS构造函数及new运算符 JS原型对象和原型链 函数作用域和作用域链 干货分享:让你分分钟学会JS闭包 深入理解...

  • JS进阶系列

    在JS入门难点解析系列中,我们对JS的一些重要概念,比如:作用域,作用域链,原型,原型链,继承,活动对象,this...

  • js 作用域链 和 原型链

    作用域链 js拥有全局作用域(window)、函数作用域、块级作用域(es6)。块级作用域是es6开始才拥有的,因...

  • JavaScript 函数闭包(colsure)

    理解闭包,你首先必须理解JS的变量作用域,JavaScript作用域和作用域链。 ES6之前,变量的作用域分为全局...

网友评论

      本文标题:JS作用域链

      本文链接:https://www.haomeiwen.com/subject/zesvsctx.html