资讯专栏INFORMATION COLUMN

JS 执行上下文栈 / 作用域链

yunhao / 929人阅读

摘要:每一个执行上下文可以访问的对象包括自身的作用域和父执行上下文的作用域和父父执行上下文作用域直到全局作用域,这就产生了作用域链。语句结束后,作用域链恢复正常。

0、自己理解

代码执行或函数调用生成执行上下文(只有当前执行上下文有执行权),该执行上下文内只能访问当前执行上下文的变量、函数和上一级执行上下文中的变量、函数,激活下一个执行上下文的时候执行权转移到新的执行上下文,形成执行上下文栈。

作用域是当前执行上下文中能访问的变量、函数的集合,执行上下文中只能访问当前作用域和其上执行上下文的作用域,由此形成作用域链

1、执行上下文(栈)

每一次代码执行和函数调用都会产生一个执行环境,称为执行上下文(context stack)。
一个执行上下文caller又可以激活(调用)另一个执行上下文callee,这时caller会暂停自身的执行把控制权交给callee进入callee的执行上下文,callee执行完毕后将控制权交回callercallee可以用return或者抛出Exception来结束自己的执行。
多个执行上下文会形成执行上下文栈,最顶层是当前执行上下文,底层是全局执行上下文。

2、作用域(链)

作用域(scope chain)是每一个执行上下文自身持有的活动对象的集合,如在本执行上下文中声明的变量和函数以及方法参数传入的对象。
每一个执行上下文可以访问的对象包括自身的作用域和父执行上下文的作用域和父父执行上下文作用域直到全局作用域,这就产生了作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。

作用域链的工作原理跟原型链十分相似:如果本身的作用域中查找不到标识符,那么就查找父作用域,直到顶层。
目前假设作用域的联动是用的__parent__对象,它指向作用域链的下一个对象。(在ES5中,确实有一个outer链接)

全局上下文的作用域包含Object.prototype中的对象,with和catch会改变作用域链,在with中,查询__parent__之前会先去查询__proto__,会使作用域链增大。

2.1 作用域链中的名称解析顺序

javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:

语言内置:所有的作用域中都有 this 和 arguments 关键字

形式参数:函数的参数在函数作用域中都是有效的

函数声明:形如function foo() {}

变量声明:形如var bar;

名字声明的优先级如上所示,也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,无论其在代码中的顺序如何;形式参数会覆盖变量声明。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。

(function(){
    var foo;
    console.log(typeof foo); //function
    
    function foo(){}

    foo = "foo";
    console.log(typeof foo); //string
})();

如果形参中有多个同名变量,那么最后一个同名参数会覆盖其他同名参数,即使最后一个同名参数未定义;以上的名字解析优先级存在例外,比如可以覆盖语言内置的名字arguments。

2.2 with改变作用域链

with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。

person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}};
with(person.wife){
    console.log(name);
}

with语句将person.wife添加到当前作用域链的头部,所以输出的就是lwy。with语句结束后,作用域链恢复正常。

3、二维作用域链查找

源于ECMAScript的原型特性。如果一个属性在对象中没有直接找到,查询将在原型链中继续。即常说的二维链查找。

作用域链环节;

每个作用域链-深入到原型链环节

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

参考: 
1、执行上下文(栈)/作用域(链)/with
2、Js 作用域与作用域链与执行上下文不得不说的故事

PS:欢迎大家关注我的公众号【前端下午茶】,一起加油吧~

另外可以加入「前端下午茶交流群」微信群,长按识别下面二维码即可加我好友,备注加群,我拉你入群~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92024.html

相关文章

  • js深入(三)作用域链与闭包

    摘要:在之前我们根绝对象的原型说过了的原型链,那么同样的万物皆对象,函数也同样存在这么一个链式的关系,就是函数的作用域链作用域链首先先来回顾一下之前讲到的原型链的寻找机制,就是实例会先从本身开始找,没有的话会一级一级的网上翻,直到顶端没有就会报一 在之前我们根绝对象的原型说过了js的原型链,那么同样的js 万物皆对象,函数也同样存在这么一个链式的关系,就是函数的作用域链 作用域链 首先先来回...

    blair 评论0 收藏0
  • 深入学习js之——作用域链

    摘要:开篇作用域是每种计算机语言最重要的基础之一,因此要想深入的学习作用域和作用域链就是个绕不开的话题。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。这时候执行上下文的作用域链,我们命名为至此,作用域链创建完毕。 开篇 作用域是每种计算机语言最重要的基础之一,因此要想深入的学习JavaScript,作用域和作用域链就是个绕不开的话题。 在《深入学习js之—-执行上下文栈》中我们提到...

    lemanli 评论0 收藏0
  • 深入学习js之——执行下文

    摘要:思考题在深入学习之词法作用域和动态作用域中,提出这样一道思考题思考题一思考题二两段代码都会打印但是还是有些许差异的,本文就详细的解析执行上下文栈和执行上下文的具体变化过程。 在《深入学习js之——执行上下文栈》中说过,当JavaScript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context) 对于每一个执行上下文,都有...

    baukh789 评论0 收藏0
  • 解密JavaScript执行下文

    摘要:执行上下文栈首先我们先了解一下什么是执行上下文栈。那么随着我们的执行上下文数量的增加,引擎又如何去管理这些执行上下文呢这时便有了执行上下文栈。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。 执行上下文栈 首先我们先了解一下什么是执行上下文栈(Execution context stack)。 showImg(https://segmentfault.com/img/remot...

    JeOam 评论0 收藏0
  • [译]执行下文作用域链JS内部机制

    摘要:执行上下文作用域链和内部机制一执行上下文执行上下文是代码的执行环境,它包括的值变量对象和函数。创建作用域链一旦可变对象创建完,引擎就开始初始化作用域链。 执行上下文、作用域链和JS内部机制(Execution context, Scope chain and JavaScript internals) 一、执行上下文 执行上下文(Execution context EC)是js代码的执...

    caozhijian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<