资讯专栏INFORMATION COLUMN

一起再看执行上下文/作用域链/原型链

ninefive / 2464人阅读

摘要:试想一下现在写了一个函数,并没有调用这个函数,那么现在有执行上下文吗现在有作用域吗现在有作用域链吗现在有原型链吗执行上下文没有,执行上下文是调用时产生的。

作为小白入坑的这段时间,这三个概念很早便深入我心,但是却总感觉模模糊糊不知道该怎么讲清楚其中的关系,甚至有时候还会混淆,正好今天拿出来复盘一下。

举三个栗子 执行上下文

简单直白的讲执行上下文就是一种环境。

类比一个卖猪肉的宇宙人小明,小明今天想要卖猪肉,那么首先宇宙是最根本的环境,在宇宙茫茫星海中他选择了在地球上卖,所以他来到了地球,在地球这么多的地方选择了中国某县的猪肉铺。至此他就开始卖猪肉了。你想想看,很大的空间里,小明先把宇宙压入栈底,而后把存在与其中的地球又压入栈内,然后又把地球中的中国某县压入栈内部。是不是很像执行环境的压栈操作?当他在某县赚够了码农的钱后被宇宙警察发现非法卖肉,便准备溜了,先从某县走出,然后逃离地球,最后跑出宇宙。


(出入栈操作)

在每个执行上下文环境中都会提供一些变量。这是不是很像每个环境独有的物质基础?比如在地球这个执行上下文环境中还有其他一些地方可供选择,在某县卖肉的时候你需要的砍刀不就是这个环境提供给你的变量?

回顾一下:每个执行上下文是一种环境,这种环境有大有小(大小指的是内部包含的变量多少)在调用某个函数时就将这个函数的执行上下文压入栈中,同时执行上下文中的变量对象被激活可用变为活动变量。函数调用完毕就把此函数的执行上下文出栈,当然连同这个环境中的变量对象一起被踢出局,同时激活当前栈顶的执行上下文的变量对象。

作用域链

作用域链就是一种寻找变量的链条关系,每个执行上下文中包含本环境中的变量对象并创建链条指向他的前一作用域。

接上个例子,小明在某县猪肉铺卖猪肉的时候,为了杀一头猪妖,他必须找到一把锋利的宝刀,但是寻遍了中国某县也没有适合的刀,于是他考虑是去日本打造一把军刀还是在宇宙深处找一找有没有适合的刀?犹豫不决,但是他毕竟是个商人,为了把刀出去大动干戈还花钱,不如就地球内随便找把刀吧,但必须是他要的那个独一无二的类型才能发挥他杀猪的最高境界!于是他在地球某处终于找到了那把绝世宝刀!顺利杀妖抱得美人归。

至此,我们来分析一下:小明杀猪妖就是调用某个函数解决实际需求,但是他需要某个独一无二的宝刀(变量),在中国某县并未找到(当前作用域中并没有定义此变量),于是他不得已在地球范围内寻找(顺着作用域链条在前一作用域中寻找),在地球中找到了!(前一作用域中找到了此变量),于是愉快的杀猪去了(找到了变量顺利解决了实际需求)。

回顾一下:作用域链是由每个作用域链接成的呈链状变量对象集合,当前作用域不存在的变量就会依次向前一作用域寻找,直到在根作用域在寻找,并且只能按照一定的顺序寻找,不能够逆着顺序寻找。

原型链

原型链就是一种对象和创建此对象的对象之间的呈链式的关系链条。

还是上个例子吧,小明觉得卖猪肉太不赚钱,于是搞起了养殖业,他从某猪户中购得一怀了崽的猪,过了几天便下崽了,于是就变成了猪生猪代代相传。这个小明发现每一代猪都是俩并且这俩猪还只和他猪爸猪妈交流。

到这大家可以分析一下:这第一代怀了崽的猪就是null,后期由null产生了object与object.prototype这两个对象,再由这两个对象派生出了其他对象。或许一张图你会看得更明白。

回顾一下:原型链其实就是对象和自己父母的关系,父母在和爷奶的关系。每代之间会有特点添加进去,在你这里需要调用某个方法你却没有时,可以向上一直找寻找到后调用。

分析关系

红宝书中讲:由多个执行上下文的变量对象构成的链表就叫做作用域链,所以作用域链表的产生是依附于执行上下文的变量对象的,根据每个执行上下文有自己的作用域,而后根据压栈的关系组合成作用域链表。

原型链和他俩不掺合,原型链其实在构造对象的过程中就已经产生了,除非手动的修改他的原型,这也是我们平时在调用一些自带的API,并没有写具体实现却能正常跑下来的原因。

试想一下:现在写了一个函数,并没有调用这个函数,那么现在有执行上下文吗?现在有作用域吗?现在有作用域链吗?现在有原型链吗?

执行上下文没有,执行上下文是调用时产生的。作用域已经存在了,书写完一个函数就确定了函数自己的作用域。那么作用域链呢?当然是执行上下文压栈是才存在的。原型链也是函数写完时他就已经存在了,和是否调用该函数并无关系。

感谢各位看官至此,希望批评指正。

参考资料:

JavaScript高级程序设计第3版

深入理解javascript原型和闭包(完结)

(图片来源于网络)

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

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

相关文章

  • 「译文」JavaScript核心

    摘要:在这个情况下我们可能需要使用构造函数,其以指定的模式来创造对象。构造函数也有自己的,值为,也通过其属性关联到。从逻辑上来说,这是以栈的形式实现的,它叫作执行上下文栈。 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ 对象 原型链 构造函数 执行上下文栈 执行上下文 变量对象 活动对象 作用域链 闭包 Thi...

    高璐 评论0 收藏0
  • JS 执行下文栈 / 作用

    摘要:每一个执行上下文可以访问的对象包括自身的作用域和父执行上下文的作用域和父父执行上下文作用域直到全局作用域,这就产生了作用域链。语句结束后,作用域链恢复正常。 0、自己理解 代码执行或函数调用生成执行上下文(只有当前执行上下文有执行权),该执行上下文内只能访问当前执行上下文的变量、函数和上一级执行上下文中的变量、函数,激活下一个执行上下文的时候执行权转移到新的执行上下文,形成执行上下文栈...

    yunhao 评论0 收藏0
  • 高性能JavaScript阅读简记(一)

    摘要:对于直接量和局部变量的访问性能差异微不足道,性能消耗代价高一些的是全局变量数组项对象成员。当一个函数被创建后,作用域链中被放入可访问的对象。同样会改变作用域链,带来性能问题。 早前阅读高性能JavaScript一书所做笔记。 一、Loading and Execution 加载和运行 从加载和运行角度优化,源于JavaScript运行会阻塞UI更新,JavaScript脚本的下载、解析...

    sorra 评论0 收藏0
  • 高性能JavaScript阅读简记(一)

    摘要:对于直接量和局部变量的访问性能差异微不足道,性能消耗代价高一些的是全局变量数组项对象成员。当一个函数被创建后,作用域链中被放入可访问的对象。同样会改变作用域链,带来性能问题。 早前阅读高性能JavaScript一书所做笔记。 一、Loading and Execution 加载和运行 从加载和运行角度优化,源于JavaScript运行会阻塞UI更新,JavaScript脚本的下载、解析...

    zhangrxiang 评论0 收藏0
  • 前端优化-Javascript篇(3.标识符查找优化)

    摘要:下面我跟大家分享关于标识符查找方面的优化问题。这个变量对象会首先被放入作用域链中。执行上下文也有一个作用域链,这个作用域链就是用来进行变量查找的。当执行上下文创建时,它的作用域链会用函数的属性来初始化。   前面两篇文章介绍了Javascript文件在页面中位置以及异步加载问题对前端性能的影响。不过受限于单线程的原因,不管采用哪种方法,只要Javascript进行了耗时的工作,就都会引...

    KaltZK 评论0 收藏0

发表评论

0条评论

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