v8::FunctionCallbackInfo
类区分This
和Holder
。我知道JavaScript中的this
是什么,并假设This
反映了该设置。但我对Holder
的概念只有一个模糊的概念,而且我不应该在何时使用Holder
而不是This
。
特别是,在编写基于nan的node.js扩展并展开ObjectWrap
时,我应该通过哪些?
目前node::ObjectWrap
documentation有使用Holder
的示例,而current Nan::ObjectWrap
documentation使用This
,所以“只需按照文档中的示例”帮助回答此问题。
答案 0 :(得分:3)
在写上面的问题时,我做了一些挖掘,最终在v8-users Google Group找到了一些相关的主题。我将引用这两个与我最相关的帖子中的一小部分,但它们是脱离了上下文的,所以包含的内容可能值得阅读以获取更多信息。格式化标记由我添加。
Christian 'Little Jim' Plesner wrote in 2009:
简而言之:如果您通过
Signature
指定函数必须 仅在函数模板T
的实例上调用,返回值Holder
保证保留从T
或其他人创建的实例 直接或间接的功能模板 来自FunctionTemplate::Inherit
的{{1}}。没有保证持有 类型T
。
此语句由Stephan Beal in 2010引用。稍后在同一个帖子中Anton Muhin wrote:
整体
This
应始终位于Holder
和This
的原型链中 因此,如果您阅读该属性,您可以自由使用这两个属性。然而 如果This() != Holder()
设置属性的行为会有所不同 - 该物业将以不同的对象结束。
这方面又是repeated by Ben Noordhuis in 2014。
第一个声明似乎表明Holder
是正确的,应该更改nan文档。后者提醒我们,一般情况下,This
更合适,除非与ObjectWrap
之类的内部状态直接交互。
有关This
如何出现意外类型的第一篇帖子中给出的示例如下:
var x = { }
x.__proto__ = document;
var div = x.createElement('div');
为此,他写道“出于兼容性原因,我们必须允许
这个”。尝试使用基于纳米的扩展类型(来自nan测试套件),我发现这些天上面似乎导致了TypeError: Illegal invocation
。显然,签名验证语义已经有所改变。对于ObjectWrap::Unwrap
这些天来说,使用This
还是Holder
似乎并不重要。但是,对于节点0.10,情况看起来不同,所以我认为至少对于方法应该首选Holder
,并就此提交nan pull request #524。
访问者的情况要复杂得多。使用Holder()
对原型上安装的访问器不起作用,因此显然要么必须在实例模板上安装访问器,要么使用This
并进行一些手动类型检查。