06|作用域链:V8是如何查找变量的?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
V8引擎如何查找变量?本文深入探讨了作用域链的概念和工作原理,阐述了作用域链在变量查找中的关键作用。通过详细的示例代码演示了在函数内部查找变量的过程,以及函数作用域和全局作用域的区别。文章还解释了V8引擎在执行代码时创建作用域的过程,并通过图示展示了作用域链的工作方式。此外,还介绍了词法作用域和动态作用域的区别。通过本文,读者可以快速了解V8引擎中作用域链的工作原理和JavaScript中作用域的相关概念。文章深入浅出地解释了V8引擎中变量查找的机制,为读者提供了清晰的技术视角和理解途径。
《图解 Google V8》,新⼈⾸单¥59
全部留言(31)
- 最新
- 精选
- Geek_f老师,下面这题困扰很久了,不知道作用域链该怎么画,想请教下: var a = []; for(let i = 0;i<10;i++){ a[i]=function(){ console.log(i) } }; a[2]();
作者回复: let定义的i会运行for的块级作用域中,每次执行一次循环,都会创建一个块级作用域。 在这个块级作用域中,你又定义了一个函数,而这个函数又引用了函数外部的i变量,那么这就产生了闭包,也就是说,所有块级作用域中的i都不会被销毁,你在这里执行了10次循环,那么也就创建了10个块级作用域,这十个块级作用域中的变量i都会被保存在内存中。 那么当你再次调用该a[n]()时,v8就会拿出闭包中的变量i,并将其打印出来,因为每个闭包中的i值都不同,所以a[n]()时,打印出来的值就是n,这个就非常符合直觉了。 但是如果你将for循环中的i变量声明改成var,那么并不会产生块级作用域,那么函数引用的i就是全局作用域中的了,由于全局作用域中只有一个,那么在执行for循环的时候,i的值会一直被改变,最后是10,所以最终你执行a[n]()时,无论n是多少,打印出来的都是10. 那么这就是bug之源了。
2020-05-19357 - 刘大夫和 this 对比就很好记了,可以简单的理解为 this 是看函数的调用位置,作用域是看函数的声明位置。除了箭头函数等那些特殊的情况
作者回复: 对,可以认为this是用来弥补JavaScript没有动态作用域特性的🤫
2020-04-07332 - 杨越老师,昨天面试小红书,有个问题请教下: function f(){setTimeOut(fn,0)}面试官问我这种调用会不会导致内存溢出?
作者回复: fn是啥?是函数f吧? 如果fn是f的话,那么不会溢出啊,因为这是异步调用,下次执行f函数时,已经在新的栈中执行了,所以当前栈不会发生溢出! 理解这个问题核心是理解事件循环和消息队列这套机制,这个专栏会有几篇文章介绍事件循环系统的,另外我的上个《浏览器专栏》对这块介绍的比较详细!
2020-03-28630 - Bazinga老师,在大量数据时(百万级别) ,foreach循环比for循环的执行效率低,是因为什么
作者回复: 因为foreach有函数回调过程啊,每次回调都要额外创建新的额外的栈贞,新的上下文,那么效率也就随之下来了
2020-03-29416 - Jack.Huang根据ECMAScript最新规范,函数对象有一个[[Environment]]内部属性,保存的是函数创建时当前正在执行的上下文环境,当函数被调用并创建执行上下文时会以[[Environment]]的值初始化作用域链,所以从规范也可以得知函数的作用域只跟函数创建时的当前上下文环境有关。 规范中关于[[Environment]]的描述:https://tc39.es/ecma262/#sec-ecmascript-function-objects
作者回复: 赞
2020-06-2913 - 零维老师,请问一下我下面关于作用域的理解是否正确: 如果我运行一个 js 文件,在解释阶段生成 AST 树之后,紧接着,这个 js 文件的所有的作用域(函数作用域,块级作用域,全局作用域)就都已经确定了,就算有某些函数没有被执行,它的作用域内含有哪些变量也已经确定了,但是这些变量还都不会真实存在栈或堆中。也就是说,某个未执行函数的执行上下文中的变量环境和词法环境现在也已经确定了。 这样的理解对吗?
作者回复: 正常情况下是这样的,单是执行eval的情况,这个eval方法很有破坏性,因为在执行eval之前,引擎并不知道eval要执行的内容,也就没有办法提前做预解析
2020-05-194 - 离人生巅峰还差一只猫🐈老师你好,有个问题想请教下: 之前提到在编译阶段就会生成作用域和AST,在本节中又提到函数在执行时才会创建作用域。那么编译时创建的作用域具体是哪些作用域,因为通过d8 print-scopes发现都所有作用域都存在
作者回复: 是打印所有的作用域,编译的时候就编译什么代码就创建什么代码的作用域。 比如执行全局代码的时候,只会生成全局作用域,函数的作用域就不会被生成,当执行某个函数时,就会生成函数的作用域了。
2020-06-303 - 于你之前看《浏览器运行原理》时候,说的是作用域链是在定义代码的时候决定的,当时的有点迷糊,今天突然看明白了,看来还是需要反复巩固知识啊,给老师点个赞!
作者回复: 👍
2020-04-092 - chengl老师你好,为了更好的理解效果,建议有打印信息的代码,在代码底部增加打印结果,便于结合理解,有些代码虽然很简单,但是就怕理解错了。
作者回复: 好,回头我修订的时候我来补充
2020-04-091 - zlxag老师你这个图片怎么画的呀
作者回复: keynote
2020-04-0321