我对V8 ObjectTemplate的Set和SetAccessor方法之间的区别感到困惑。我的问题有一个简单的上下文和 4个具体的子问题。
假设我有代码片段,希望为定位JS上下文提供全局对象global
。 global
有一个属性x
,其值为int值。 global
还有一个属性log
,这是一个函数。所有代码段都来自V8的来源,process.cc和Embedder's Guide是准确的。
HandleScope handle_scope(GetIsolate());
// Create a template for the global object where we set the
// built-in global functions.
Local<ObjectTemplate> global = ObjectTemplate::New(GetIsolate());
global->Set(String::NewFromUtf8(GetIsolate(), "log",
NewStringType::kNormal).ToLocalChecked(),
FunctionTemplate::New(GetIsolate(), LogCallback));
因此,此代码段向全局提供函数log
。然后从Embedder的指南到访问者,它说
访问器是一种C ++回调,它在JavaScript脚本访问对象属性时计算并返回一个值。使用SetAccessor方法通过对象模板配置访问器。
代码段如下:
void XGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
info.GetReturnValue().Set(x);
}
void XSetter(Local<String> property, Local<Value> value,
const PropertyCallbackInfo<Value>& info) {
x = value->Int32Value();
}
// YGetter/YSetter are so similar they are omitted for brevity
Local<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);
global_templ->SetAccessor(String::NewFromUtf8(isolate, "x"), XGetter, XSetter);
global_templ->SetAccessor(String::NewFromUtf8(isolate, "y"), YGetter, YSetter);
Persistent<Context> context = Context::New(isolate, NULL, global_templ);
据我了解这段代码片段,正如描述所示,它为全局提供了一些整数值x
。
现在,从V8的源代码,我看到ObjectTemplate没有Set方法,相反,它继承自父类Template。从模板的source code开始,它说:
/**
* Adds a property to each instance created by this template.
*
* The property must be defined either as a primitive value, or a template.
*/
void Set(Local<Name> name, Local<Data> value,
propertyAttribute attributes = None);
模板的Set方法说它可以为模板的实例设置原始值,然后 我可以使用Set在第二个代码片段中设置x
而不是使用SetAccessor吗
如果对问题1的回答是正确的,那么在使用x
和SetMethod
之间设置Set
有什么区别?不同之处在于JS中对Set
设置的属性的任何修改都不会反映在C ++中吗?
如果对问题1的回答是错误的,那为什么我不能在X
上使用Set?
从访问者的描述中,它说它计算并返回 值 。那么这是否意味着我们不使用SetAccessor
来返回函数?我很困惑因为我主要写JS和Haskell。两种语言都破坏了我将函数作为值。
现在我知道通过实际构建样本来验证我的所有假设应该很容易,但是我在编译V8源代码时遇到了困难,因此我要求任何帮助。
感谢您提前付出的努力!
答案 0 :(得分:1)
1。是。
2。 Set
是C ++等效项(模数属性属性):
Object.defineProperty(global, "x", {value: 3})
SetAccessor
是C ++的等价物:
Object.defineProperty(global, "x", {get: function XGetter() { return ...; },
set: function XSetter(val) { ... }});
正如你的建议,结果是在Set
的情况下,C ++方面无法知道该值是否从JavaScript端改变了。
3。不适用
4. getter可以返回您想要的任何值;特别是价值可以是一种功能。