SetAccessor 和 SetAccessorProperty,有什么区别吗?
SetAccessor and SetAccessorProperty, any difference?
V8 的 ObjectTemplate
为我们提供了两种方法来将所谓的访问器 属性 附加到实例化的对象。
第一个是 ObjectTemplate::SetAccessor
:
/**
* Sets an accessor on the object template.
*
* Whenever the property with the given name is accessed on objects
* created from this ObjectTemplate the getter and setter callbacks
* are called instead of getting and setting the property directly
* on the JavaScript object.
*
* \param name The name of the property for which an accessor is added.
* \param getter The callback to invoke when getting the property.
* \param setter The callback to invoke when setting the property.
* \param data A piece of data that will be passed to the getter and setter
* callbacks whenever they are invoked.
* \param settings Access control settings for the accessor. This is a bit
* field consisting of one of more of
* DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
* The default is to not allow cross-context access.
* ALL_CAN_READ means that all cross-context reads are allowed.
* ALL_CAN_WRITE means that all cross-context writes are allowed.
* The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
* cross-context access.
* \param attribute The attributes of the property for which an accessor
* is added.
* \param signature The signature describes valid receivers for the accessor
* and is used to perform implicit instance checks against them. If the
* receiver is incompatible (i.e. is not an instance of the constructor as
* defined by FunctionTemplate::HasInstance()), an implicit TypeError is
* thrown and no callback is invoked.
*/
void SetAccessor(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), AccessControl settings = DEFAULT, // note the data is on the template level.
PropertyAttribute attribute = None, // not on the instance level.
Local<AccessorSignature> signature = Local<AccessorSignature>(),
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
第二个是Template::SetAccessorProperty
:
void SetAccessorProperty(
Local<Name> name, // The latter one is called data property.
Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
有两个非常相似的 API让我很困惑。
不幸的是,没有 没有 描述它们差异的文档,所以我必须 experiment on my own. I found that the combination of Holder()
and SetAccessor()
will break, while other combinations of Holder() or This()
and SetAccessor() or SetAccessorProperty()
work fine. On a previous post 我 运行 进入这个失败的组合并且被愚弄相信出了什么问题 Holder() or This()
。但是经过实验我现在认为是SetAccessor
出了问题
我的问题是,SetAccessor
是否已弃用 API?如果是这样,我们所要做的就是停止使用它。如果不是这样,请解释一下它们的不同之处,尤其是导致此故障的原因。非常感谢热心和经验丰富的V8开发人员!
我同意名称可能有点混乱;两者都没有被弃用。区别如下:
SetAccessor
creates a "magic" data 属性: 它看起来像数据 属性 to JavaScript (getOwnPropertyDescriptor
returns {value: ..., ...}
),但是当 reading/writing 属性 时,将调用您指定的 C++ 回调。对于内置示例,请考虑 Array.prototype.length
(当您使用 .length
赋值来缩短数组时,特别是 setter 必须做额外的工作)。
SetAccessorProperty
创建一个常规访问器 属性,即 getOwnPropertyDescriptor
returns {get: ..., set: ..., ...}
。一个内置示例是 Int32Array.prototype.__proto__.byteLength
。名称 "SetAccessorProperty" 反映了 the JS spec 调用这些属性的事实 "accessor properties".
很可能在许多情况下,这种差异无关紧要:接口 JavaScript 代码可以读取 and/or 写入属性。但有时您可能有理由关心这种区别,在这种情况下,V8 的 API 为您提供了这种灵活性。
V8 的 ObjectTemplate
为我们提供了两种方法来将所谓的访问器 属性 附加到实例化的对象。
第一个是 ObjectTemplate::SetAccessor
:
/**
* Sets an accessor on the object template.
*
* Whenever the property with the given name is accessed on objects
* created from this ObjectTemplate the getter and setter callbacks
* are called instead of getting and setting the property directly
* on the JavaScript object.
*
* \param name The name of the property for which an accessor is added.
* \param getter The callback to invoke when getting the property.
* \param setter The callback to invoke when setting the property.
* \param data A piece of data that will be passed to the getter and setter
* callbacks whenever they are invoked.
* \param settings Access control settings for the accessor. This is a bit
* field consisting of one of more of
* DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
* The default is to not allow cross-context access.
* ALL_CAN_READ means that all cross-context reads are allowed.
* ALL_CAN_WRITE means that all cross-context writes are allowed.
* The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
* cross-context access.
* \param attribute The attributes of the property for which an accessor
* is added.
* \param signature The signature describes valid receivers for the accessor
* and is used to perform implicit instance checks against them. If the
* receiver is incompatible (i.e. is not an instance of the constructor as
* defined by FunctionTemplate::HasInstance()), an implicit TypeError is
* thrown and no callback is invoked.
*/
void SetAccessor(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), AccessControl settings = DEFAULT, // note the data is on the template level.
PropertyAttribute attribute = None, // not on the instance level.
Local<AccessorSignature> signature = Local<AccessorSignature>(),
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
第二个是Template::SetAccessorProperty
:
void SetAccessorProperty(
Local<Name> name, // The latter one is called data property.
Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
有两个非常相似的 API让我很困惑。
不幸的是,没有 没有 描述它们差异的文档,所以我必须 experiment on my own. I found that the combination of Holder()
and SetAccessor()
will break, while other combinations of Holder() or This()
and SetAccessor() or SetAccessorProperty()
work fine. On a previous post 我 运行 进入这个失败的组合并且被愚弄相信出了什么问题 Holder() or This()
。但是经过实验我现在认为是SetAccessor
出了问题
我的问题是,SetAccessor
是否已弃用 API?如果是这样,我们所要做的就是停止使用它。如果不是这样,请解释一下它们的不同之处,尤其是导致此故障的原因。非常感谢热心和经验丰富的V8开发人员!
我同意名称可能有点混乱;两者都没有被弃用。区别如下:
SetAccessor
creates a "magic" data 属性: 它看起来像数据 属性 to JavaScript (getOwnPropertyDescriptor
returns {value: ..., ...}
),但是当 reading/writing 属性 时,将调用您指定的 C++ 回调。对于内置示例,请考虑 Array.prototype.length
(当您使用 .length
赋值来缩短数组时,特别是 setter 必须做额外的工作)。
SetAccessorProperty
创建一个常规访问器 属性,即 getOwnPropertyDescriptor
returns {get: ..., set: ..., ...}
。一个内置示例是 Int32Array.prototype.__proto__.byteLength
。名称 "SetAccessorProperty" 反映了 the JS spec 调用这些属性的事实 "accessor properties".
很可能在许多情况下,这种差异无关紧要:接口 JavaScript 代码可以读取 and/or 写入属性。但有时您可能有理由关心这种区别,在这种情况下,V8 的 API 为您提供了这种灵活性。