v8::ObjectTemplate::SetAccessor and v8::Template::Set - Diff
v8::ObjectTemplate::SetAccessor and v8::Template::Set - Difference
我对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
。然后从嵌入者指南到访问器,它说
访问器是一个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 继承而来的。从模板的源代码中,它说:
/**
* 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 的答案是正确的,那么使用
SetMethod
和Set
之间设置x
有什么区别?区别在于 JS 中对Set
设置的属性的任何修改都不会反映在C++中吗?如果问题 1 的答案是假的,那么为什么我不能在
X
上使用 Set ?从访问器的描述来看,它说它计算并返回值。那么这是否意味着我们不使用
SetAccessor
来返回函数?我很困惑,因为我主要写JS和Haskell。这两种语言都宠坏了我把函数当作价值观。
现在我知道通过实际构建样本来验证我的所有假设应该很容易,但我在编译 V8 源代码时遇到困难,因此我寻求任何帮助。
提前感谢您的任何努力!
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 可以返回任何你想要的值;特别是这个值可以是一个函数。
- 示例外壳应用程序显示的 V8 "segmentation fault (core dumped)"错误
- 在 G++ v8.2.0 中使用 std::experimental::可选
- 如何为 v8::P ersistent<v8::Function> 创建到 c++ 函数的包装器
- v8::HandleScope::CreateHandle() # 中的致命错误无法在没有 HandleScope 的情
- 如何将节点 V8 字符串转换为 C++ 字符串
- 在 C++ 中嵌入 V8 会导致与 libcpp 相关的"unrecognized external symbol"错误
- 当我使用 V8 库中的 GetInternalField() 时出现分段错误
- 在 v8 JavaScript 中重复调用C++是否有巨大的开销?
- diff: output.txt: 没有这样的文件或目录
- 我可以使用谷歌 v8 在回调函数中获取 JavaScript 函数C++源文本吗?
- 与纯 V8 相比,NodeJS 是否有任何性能缺陷或显著开销?
- V8垃圾收集器回调,用于测量GC活动
- 如何在 C++ 中从 V8 调用 Javascript 函数
- 如何将 v8::FunctionCallbackInfo<v8::Value> 数组从一个隔离复制到另一个隔离?
- 使用导入的函数从嵌入式v8调用webassembly
- v8 源代码中 ArrayMap 函数的回调 fn 参数是什么?
- 如何在 v8 Javascript 中的多个函数中使用相同的上下文?
- 如何使用 v8 本机插件将 C++ 数组交付到 Node.js
- 存储/传递 v8 承诺解析器供以后使用的最佳实践?(结合C++线程)
- v8::ObjectTemplate::SetAccessor and v8::Template::Set - Diff