这与 ObjectWrap::Unwrap 的持有人

This vs. Holder for ObjectWrap::Unwrap

v8::FunctionCallbackInfoclass区分ThisHolder。我知道 JavaScript 中的 this 是什么,并假设 This 反映了该设置。但是我对 Holder 是什么只有一个模糊的概念,对于什么时候应该使用 Holder 而不是 This 几乎一无所知。

特别是,在编写基于 nan 的 node.js 扩展和解包 ObjectWrap 时,我应该传递哪些?

目前 node::ObjectWrap documentation has examples using Holder while current Nan::ObjectWrap documentation 使用 This,因此“仅按照文档中的示例”无助于回答此问题。

在写上面的问题时,我进行了更多挖掘,最终在 v8-users Google Group 上找到了一些相关主题。我将引用这两篇文章中与我最相关的一小部分,但它们是断章取义的,因此包含的主题可能值得阅读以获取更多信息。我添加的格式标记。

Christian 'Little Jim' Plesner wrote in 2009:

In short: if you specify, through a Signature, that a function must only be called on instances of function template T, the value returned by Holder is guaranteed to hold an instance created from T or another function template that directly or indirectly FunctionTemplate::Inherits from T. No guarantees hold about the type of This.

此语句被Stephan Beal in 2010. Later in that same thread, Anton Muhin wrote:

引用

Overall Holder should be always in the prototype chain of This and hence if you read the property, you can freely use both. However setting the property would behave differently if This() != Holder() — the property would end at different object.

这方面又是repeated by Ben Noordhuis in 2014.

第一个陈述似乎表明 Holder 是正确的,应该更改 nan 文档。后者提醒我们,一般来说,This 更合适 除非 一个人像 ObjectWrap 那样直接与某些内部状态交互。

引用的第一个帖子中给出的关于 This 可能是意外类型的示例如下:

var x = { }
x.__proto__ = document;
var div = x.createElement('div');

为此他写道“出于兼容性原因,我们必须允许 这个”。对基于 nan 的扩展类型(来自 nan 测试套件)进行相同的尝试,我发现这些天上面的内容似乎导致 TypeError: Illegal invocation。很明显,签名验证语义发生了一些变化。现在对于 ObjectWrap::Unwrap 来说,使用 This 还是 Holder 似乎已经无关紧要了。不过,对于 Node 0.10,情况看起来有所不同,所以我认为 Holder 至少对于方法来说应该是首选,并就此提交 nan pull request #524

访问者的情况要复杂得多。使用 Holder() 不适用于安装在原型上的访问器,因此显然要么必须在实例模板上安装访问器,要么使用 This 并进行一些手动类型检查。