v8 :: ObjectTemplate :: SetAccessor和v8 :: Template :: Set - 差异

时间:2018-01-30 10:29:28

标签: c++ v8

我对V8 ObjectTemplate的Set和SetAccessor方法之间的区别感到困惑。我的问题有一个简单的上下文 4个具体的子问题

上下文

假设我有代码片段,希望为定位JS上下文提供全局对象globalglobal有一个属性x,其值为int值。 global还有一个属性log,这是一个函数。所有代码段都来自V8的来源,process.ccEmbedder'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);

问题

  1. 模板的Set方法说它可以为模板的实例设置原始值,然后 我可以使用Set在第二个代码片段中设置x而不是使用SetAccessor吗

  2. 如果对问题1的回答是正确的,那么在使用xSetMethod之间设置Set有什么区别?不同之处在于JS中对Set设置的属性的任何修改都不会反映在C ++中吗?

  3. 如果对问题1的回答是错误的,那为什么我不能在X上使用Set?

  4. 从访问者的描述中,它说它计算并返回 。那么这是否意味着我们不使用SetAccessor来返回函数?我很困惑因为我主要写JS和Haskell。两种语言都破坏了我将函数作为值。

  5. 现在我知道通过实际构建样本来验证我的所有假设应该很容易,但是我在编译V8源代码时遇到了困难,因此我要求任何帮助。

    感谢您提前付出的努力!

1 个答案:

答案 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可以返回您想要的任何值;特别是价值可以是一种功能。