gpt4 book ai didi

javascript - JavaScript 宿主对象是如何实现的?

转载 作者:行者123 更新时间:2023-12-03 00:27:49 25 4
gpt4 key购买 nike

我今天在思考这个问题,然后我意识到我对此没有清晰的了解。

以下是我认为正确的一些说法(如果我错了,请纠正我):

  • DOM 是 W3C 指定的接口(interface)集合。
  • 在解析 HTML 源代码时,浏览器会创建一棵 DOM 树,其中包含实现 DOM 接口(interface)的节点。
  • ECMAScript 规范没有引用浏览器主机对象(DOM、BOM、HTML5 API 等)。
  • DOM 的实际实现方式取决于浏览器内部结构,并且大多数浏览器之间可能有所不同。
  • 现代 JS 解释器使用 JIT 来提高代码性能并将其翻译为字节码

我很好奇当我调用 document.getElementById('foo') 时幕后会发生什么。调用是否由解释器委托(delegate)给浏览器 native 代码,或者浏览器是否具有所有主机对象的 JS 实现?您知道他们在这方面做了什么优化吗?

我读到this overview of browser internals但它没有提及任何有关此事的内容。有时间我会看一下Chrome和FF的源码,但我想先在这里问一下。 :)

最佳答案

您的所有要点都是正确的,除了:

modern JS interpreters use JIT to improve the code performance and translate it to bytecode

应该是“...并将其翻译为 native 代码”。 SpiderMonkey(Firefox 中的 JS 引擎)在当前 JS 速度军备竞赛之前很长一段时间都作为字节码解释器工作。

在 Mozilla 的 JS-to-DOM 桥上:

主机对象通常用 C++ 实现,尽管正在进行 implement DOM in JS 的实验。 。所以当网页调用document.getElementById('foo')时,如 hsivonen 指出的那样,通过 ID 检索元素的实际工作是在 C++ 方法中完成的。

调用底层 C++ 实现的具体方式取决于 API,并且也会随着时间的推移而改变(请注意,我没有参与开发,所以可能在一些细节上有错误,这里是 a blog post by jst ,谁实际参与了创建大部分代码):

  • 在最底层,每个 JS 引擎都提供 API 来定义宿主对象。例如,浏览器可以调用 JS_DefineFunctions(如 SpiderMonkey User Guide 中所示)让引擎知道每当脚本调用具有指定名称的函数时,就应该调用提供的 C 回调。宿主对象的其他方面也是如此(例如枚举、属性 getter/setter 等)
  • 对于核心 ECMAScript 功能以及在一些棘手的 DOM 情况下,JS 引擎/浏览器直接使用这些 API 来定义主机对象及其行为,但它需要大量常见的样板代码,例如检查参数类型、将其转换为适当的 C++ 类型、错误处理等。
  • 由于一些我不会详述的原因,比如从历史上看,Mozilla 大量使用 XPCOM对于它的许多对象,包括大部分 DOM。 XPCOM 的一项功能是它与 JS 的绑定(bind),称为 XPConnect。除此之外,XPConnect 可以采用 IDL 中的接口(interface)定义(例如 nsIDOMDocument ;或更准确地说是其编译表示),向脚本公开具有指定属性的对象,然后当脚本调用 getElementById 时,执行必要的参数检查/转换并将调用直接路由到 C++ 方法 ( nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn) )
  • XPConnect 的工作方式非常低效:它将通用函数注册为要在脚本访问主机对象时执行的回调,并且这些通用函数动态地计算出在每种特定情况下需要执行的操作。 This post about quickstubs引导您完成一个示例。
  • 上一个链接中提到的“快速 stub ”是一种通过牺牲一些代码大小来优化 JS->C++ 调用时间的方法:不是总是使用知道如何进行任何类型调用的通用 C++ 函数,而是专门使用代码会在 Firefox 构建时自动生成预定义的“热门”调用列表。
  • 后来的 JIT(当时的tracemonkey)was taught to generate the code calling C++ methods作为 JS 中为“热”路径生成的 native 代码的一部分。我不确定新的 JIT (jaegermonkey) 在这方面是如何工作的。
  • "paris bindings"对象 are exposed to webpage JS不依赖 XPConnect,而是基于 WebIDL(而不是 XPCOM 时代的 IDL)生成所有必要的粘合 JSClass 代码。另请参阅从事此工作的开发人员的帖子:jstkhuey 。另请参阅How is the web-exposed DOM implemented?

我对最后三点的细节特别模糊,所以请持保留态度。

最新的改进被列为 bug 622298 的依赖项,但我并没有密切关注他们。

关于javascript - JavaScript 宿主对象是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7850378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com