5

该类v8::FunctionCallbackInfo区分ThisHolder。我知道thisJavaScript 中有什么,并假设它This反映了该设置。但是我对什么是什么只有一个模糊的概念Holder,而且对于何时应该使用Holder而不是This.

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

当前node::ObjectWrap文档有示例 usingHolder当前Nan::ObjectWrap文档使用This,因此“仅按照文档中的示例”无助于回答这个问题。

4

1 回答 1

3

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

克里斯蒂安“小吉姆”普莱斯纳在 2009 年写道:

简而言之:如果您通过 a 指定Signature只能在函数模板的实例上调用函数T,则返回的值Holder保证包含从创建的实例T或直接或间接 FunctionTemplate::Inherit从的另一个函数模板T。不保证This.

Stephan Beal 在 2010 年引用了此声明。后来在同一个帖子中,安东·穆欣(Anton Muhin)写道:

总体Holder上应该始终在原型链中This,因此如果您阅读该属性,您可以自由使用两者。但是,如果This() != Holder() 属性以不同的对象结尾,则设置属性的行为会有所不同。

Ben Noordhuis 在 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并进行一些手动类型检查。

于 2015-12-13T23:01:55.283 回答