fso*_*ety 6 javascript google-chrome v8 node.js
我一直在阅读 Javascript 的内部结构(在 chrome 浏览器的上下文中),我有几个问题似乎找不到正确的答案。
按照我的理解:
核心 Javascript(根据 ECMA 规范)包含在 V8 引擎中。
类似settimeout
的功能由浏览器的 Web API 提供。
V8 引擎包括一个调用栈,任何要执行的 Javascript 都会被推送到这个栈上。
然后通过 Web API 调用非标准函数。
这些在完成时被推送到回调队列。
一旦堆栈为空,回调队列中的任何内容都会被事件循环推入堆栈。
我的问题是当 V8 引擎解释 Javascript 代码时,它如何知道特定功能来自 Web API?Web API 是如何与引擎实际链接的?
类似setTimeout()
的API被添加到global
Javascript 中的对象中。当 JS 引擎要解析一个符号时,它会从本地范围开始并向上延伸到一系列范围。链的最末端是global
范围。
作为初始化 V8 引擎的一部分,宿主环境可以将它自己的 API 添加到 V8 引擎的全局范围内,这正是浏览器为 V8 中尚未内置的东西所做的事情。
浏览器中全局对象的概念比它应该的要混乱一些。多年来,全局对象就是window
对象。所有全局可访问的宿主环境函数,如对象的setTimeout()
属性window
。
类似地,在浏览器的顶级范围内声明任何变量都会自动使这些变量成为window
对象的属性。
这很快就变得一团糟。当 newclass
关键字出现时,他们决定不再让这种混乱变得更糟,因此在浏览器顶级范围内声明的类在全局范围内可用,但不会作为window
对象的属性添加。
当 node.js 环境出现时,他们将用户代码组织成模块,目标是尽可能少地使用全局变量。在该环境中,全局变量是名为global
. 您在 node.js 模块中的顶层声明的变量的范围仅限于模块内。没有任何东西会自动成为全局变量,但是global
如果您愿意,您可以显式地为对象分配一个新属性,例如:
global.myProperty = 3;
Run Code Online (Sandbox Code Playgroud)
尽管在 node.js 模块化设计中强烈不鼓励这样做。
因此,在初始化 V8 引擎时,浏览器环境将 ECMAScript 规范之外的任何 APIsetTimeout()
添加到浏览器中 Javascript 的顶层,例如添加到global
对象中。
归档时间: |
|
查看次数: |
1154 次 |
最近记录: |