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 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::Inherit
s from T
. No guarantees hold about the
type of This
.
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 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.
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.
Holder()
andThis()
? If you still figured it out, could you please give a comment? IfThis()
representsthis
in js, then what doesHolder()
represent in js? – Sawtoothed