v8::ArgumentsのThis()とHolder()の違い

JavaScript関数の引数であるv8::ArgumentsのメソッドにThis()とHolder()というものがあります。この2つとも、通常は JavaScriptでの this に相当するv8::Objectを返すメソッドなのですが、違いがわかりにくいので調べてみました。

This() と Holder() は何が違うのか?

以下の説明がわかりやすいと思います。

They are not the same. This() corresponds to JS 'this' and should be
operated upon when you'd like to have a normal JS semantics.


Holder() is the objects which is instance of your FunctionTemplate.


That's not always easy to see the difference, but Christian gives a
nice example: x = { __proto__: document }, x.createElements("div").
In this case This would point to the objects pointed by 'x' variable
as well and Holder would point to object pointed by 'document'.
Therefore, if you expect some internal structure (for example, many
host objects wrap native objects and store pointers to them into
internal fields), attempt to use This would fail (it should have no
internal fields, or worse, you'll get wrong pointer), but Holder
should have expected internal fields.

Google グループ

This() は JavaScript における this と同じ位置づけで所謂、関数のレシーバオブジェクトを返し、Holder() はFunctionTemplateのインスタンス(その関数を実際に保持しているオブジェクト)を返します。
引用した文で説明されている例

x = { __proto__: document };
x.createElements("div");

では This()は 'x'、Holder()は'document'になります。

この様な状況では、This() が FunctionTemplateのインスタンスと違うオブジェクトを返すためラップされたネイティブオブジェクトや内部フィールドに保存されているポインタなどを使用している場合には内部フィールドが存在しなかったり、間違ったポインタを取得してしまいます。
一方、Holder() は正しい FunctionTemplateのインスタンスを取得できるため、この問題を回避することができます。

ということで、Node.js の C++ Addon などで C++ のクラスをラップするような場合は、Holder() を使うべきです。