作用域和作用域链

作者: 高少辉_骚辉 | 来源:发表于2017-05-21 13:17 被阅读17次

一、JS的作用域

通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
在JS里面作用域分为全局作用域,局部作用域

全局作用域

变量的定义没有在任何函数内部,就都是全局变量

局部作用域

变量定义在函数的内部,那么在函数的外部则没有权限访问这个变量,对于全局环境来说,这个变量是隐藏的,且当局部变量和全局变量同名时,在局部变量的作用域内,局部变量具有更高的优先级

提前声明

var scope = "global";//全局变量的定义,没有在任何函数内部
function f(){
  console.log( scope ); //=>undefined 为局部变量,虽然代码上看上去还为定义,但是有个提前声明
  var scope = "local";//在函数内部定义,为局部变量
  console.log( scope ); //=>"local"
}

这段代码说明了,JavaScript函数里声明的所有变量(但不包含赋值,赋值位置不变)被“提前”到这个函数的最顶部。

上面的等价代码

var scope = "global";
function f(){
  var scope;            //定义了一个变量,但是为赋值
  console.log( scope ); //=>undefined
  scope = "local";
  console.log( scope ); //=>"local"
}

二、作用域链

何为作用域链呢?我想很多人听到这个时候,也挺迷茫的。因为明白作用域的都知道,作用域是限定这个名字的可用性的代码范围。那么为什么还需要来一个作用域链呢?其实是这样:作用域是实现的结果,而作用域链则是解释器是如何来完成作用域的方法

当某个函数第一次被调用时会创建一个执行环境(EC)以及相应的作用域链,并把作用域链赋值给一个特殊的内部属性[[Scope]]。然后使用 this, arguments 和其他的命名参数值来初始化函数的活动对象(AO),但是在函数的作用域链中,外部函数的活动对象始终处于第二位,以此类推。作用域的终点是全局执行环境。

作用域链图解
从上图就可以看出:
  • 当没有调用任何函数的时候,只有一个全局作用域
  • 当嵌套一个函数时,把局部作用域压入[[Scope]]的首部(0的位置,全局的编成1),而访问变量时,查找[[Scope]]这个对象的顺序是按照升序,也就是说先访问查找局部的表中是否有定义这个变量,如果没有在查找上一级,这也就可以理解为什么局部的优先级比全局的高
  • 当多层定义时,以递归的形式进行上一步
  • 当然有一个特例,就是使用with关键字,使用with时with里面的作用域直接提到作用域的顶端[[Scope]]的0的位置。
  • 当非嵌套定义,但是在一个函数里面调用了另一个函数时,这时的作用域链,将更加复杂,比如:
function fn1(){
  var a;
  fn2();
}
function fn2(){
  var b;
}

分析可知,首先新建一个fn1的执行环境,然后通过赋值函数的[[Scope]]属性中的对象构建起执行环境的作用域链,然后在fn1中调用了fn2但是fn2的定义并不是在fn1中而是全局,所以也将新建一个作用域链,它和fn1的作用域链是相互独立的,当fn2执行完以后,此作用域链删除,fn2执行环境删除,回到fn1执行环境,继续刚才的作用域链(每个执行环境有一个指向自己作用域的指针)

相关文章

  • 作用域链和闭包

    在谈作用域链之前先说一下与作用域链关系紧密的执行环境和作用域。 作用域:作用域指的是变量的适用范围。 作用域链:作...

  • 彻底搞懂JS作用域和作用域链

    作用域和作用域链 作用域:决定了代码区块中变量和其他资源的可见性; ·全局作用域和函数作用域 作用域是分层的内部可...

  • JavaScript面试考点之作用域和作用域链、执行上下文和执行

    1、作用域和作用域链 1)作用域 作用域是变量(变量作用域又称上下文)和函数生效(能被访问)的区域。作用域决定了代...

  • JS 作用域

    作用域 作用域:限制某个变量在某个区域内有效 作用域分为 全局作用域 和 局部作用域 作用域链 从里到外依次执行 ...

  • 2023-01-12

    变量提升调用栈块级作用域作用域链和闭包 闭包 => 作用域链(词法作用域) => 调用栈(栈溢出) => 上下文...

  • JavaScript核心技术开发解密读书笔记(第五章)

    第五章 作用域与作用域链 1. 作用域 常见的作用域有两种,全局作用域和函数作用域。ES6中新增了块级作用域。全局...

  • 5分钟入门闭包

    理解闭包前先要理解两个概念:作用域和作用域链。一、作用域分为: 全局作用域 函数作用域 var a = 100 f...

  • web性能实践

    一. 作用域 前面我们了解作用域概念的以及作用域链是如何运作的。 随着作用域链中的作用域数量的增加,访问当前作用域...

  • JavaScript散乱(四、细节)

    js高级 案例问题 作用域和作用域链 全局作用域也就是window和函数作用域,不考虑es6的块级作用域前提下,作...

  • javascript基础知识问答-作用域和闭包

    1.理解词法作用域和动态作用域2.理解JavaScript的作用域和作用域链3.理解JavaScript的执行上下...

网友评论

    本文标题:作用域和作用域链

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