在写上面的问题时,我做了更多的挖掘,最终在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
并进行一些手动类型检查。