The v8::FunctionCallbackInfo
class distinguishes between This
and Holder
. I know what this
is in JavaScript, and assume that This
reflects that setting. But I have only a vague notion of what Holder
is, and very little idea as to when I should use Holder
instead of This
.
In particular, when writing a nan-based node.js extension and unwrapping an ObjectWrap
, which of these should I pass?
Currently node::ObjectWrap
documentation has examples using Holder
while current Nan::ObjectWrap
documentation uses This
, so “just follow the examples in the documentation” doesn't help answering this question.
While writing the question above, I did some more digging and eventually found some relevant threads on the v8-users Google Group. I'll quote a short portion of the two posts which seem most relevant to me, but they are taken out of context, so the containing threads may well be worth reading for further information. Formatting markup added by me.
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 templateT
, the value returned byHolder
is guaranteed to hold an instance created fromT
or another function template that directly or indirectlyFunctionTemplate::Inherit
s fromT
. No guarantees hold about the type ofThis
.
This statement is referenced by Stephan Beal in 2010. Later in that same thread, Anton Muhin wrote:
Overall
Holder
should be always in the prototype chain ofThis
and hence if you read the property, you can freely use both. However setting the property would behave differently ifThis() != Holder()
— the property would end at different object.
This aspect is again repeated by Ben Noordhuis in 2014.
The first statement seems to suggest that Holder
is correct and nan documentation should be changed. The latter reminds us that in general, This
is more appropriate unless one is directly interacting with some internal state like ObjectWrap
does.
The example given in the first of the quoted posts about how This
could be of an unexpected type was the following:
var x = { }
x.__proto__ = document;
var div = x.createElement('div');
For that he wrote that “for compatibility reasons we have to allow
this”. Trying the same with a nan-based extension type (from the nan test suite) I find that these days the above appears to result in a TypeError: Illegal invocation
. So apparently the signature verification semantics have changed somewhat. It doesn't seem to matter much for ObjectWrap::Unwrap
these days whether you use This
or Holder
. Things look different for Node 0.10, though, so I think Holder
should be preferred at least for methods, and filed nan pull request #524 about this.
The situation for accessors is much more complicated. Using Holder()
won't work for accessors installed on the prototype, so apparently one either has to install accessors on the instance template, or use This
and do some manual type checking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With