v8::FunctionCallbackInfo
класс различает This
а также Holder
, я знаю что this
в JavaScript, и предположим, что This
отражает эту настройку. Но у меня есть только смутное представление о том, что Holder
есть, и очень мало идей о том, когда я должен использовать Holder
вместо This
,
В частности, при написании расширения node.js на основе nan и распаковке ObjectWrap
что из этого я должен пройти?
В настоящее время node::ObjectWrap
документация есть примеры использования Holder
в то время как ток Nan::ObjectWrap
документация использования This
так что «просто следуйте примерам в документации» не поможет ответить на этот вопрос.
Во время написания вопроса выше я немного покопался и в конце концов нашел несколько важных тем на v8-пользователи Google Group. Я процитирую короткую часть двух постов, которые кажутся мне наиболее актуальными, но они вырваны из контекста, поэтому содержащиеся в них темы, возможно, стоит прочитать для дальнейшей информации. Форматирование разметки добавлено мной.
Кристиан «Маленький Джим» Плеснер писал в 2009 году:
Короче говоря: если вы укажете, через
Signature
, что функция должна
вызываться только в экземплярах шаблона функцииT
возвращаемое значение
отHolder
гарантированно содержит экземпляр, созданный изT
или другой
шаблон функции, прямо или косвенно
FunctionTemplate::Inherit
с изT
, Нет гарантий о
типThis
,
На это утверждение ссылаются Стефан Бил в 2010 году. Позже в той же теме, Антон Мухин написал:
В общем и целом
Holder
должен быть всегда в цепочке прототиповThis
а также
следовательно, если вы читаете свойство, вы можете свободно использовать оба. тем не мение
установка свойства будет вести себя иначе, еслиThis() != Holder()
— свойство заканчивается на другом объекте.
Этот аспект снова повторил Бен Нордхёйс в 2014 году.
Первое утверждение, кажется, предполагает, что Holder
правильно и нан документация должна быть изменена. Последнее напоминает нам, что в целом 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 # 524 об этом.
Ситуация для аксессоров намного сложнее. С помощью Holder()
не будет работать для аксессоров, установленных на прототипе, поэтому очевидно, что нужно либо установить аксессоры на шаблоне экземпляра, либо использовать This
и сделать некоторую ручную проверку типов.
Других решений пока нет …