我正在使用V8向应用程序添加JavaScript支持。由于各种原因,我无法进入,我们需要能够将方法添加到FunctionTemplate中,并使这些方法出现在已经继承自它的所有FunctionTemplates中。

例如,

v8::Handle<v8::FunctionTemplate> parent;
v8::Handle<v8::FunctionTemplate> child;
child->Inherit(parent);
parent->PrototypeTemplate()->Set(isolate, "someNewMethod", v8::FunctionTemplate::New(...));


不幸的是,我发现的是,当修改父级时,子级仅具有继承时可用的方法,而且,即使我告诉孩子从父级继承,也仍然没有。获得新方法。

更糟糕的是,如果我有这样的关系:

v8::FunctionTemplate parent, firstChild;
firstChild->Inherit(parent);
parent->PrototypeTemplate()->Set(isolate, "newMethod", FunctionTemplate::New(...));
v8::FunctionTemplate secondChild;
secondChild->Inherit(parent);


那么secondChild的实例仍然仅具有parent继承时可用的firstChild方法。

据我所知,V8可能正在积极优化继承关系。从子FunctionTemplate实例化的对象不显示原型链,而是直接将方法绑定到它们。因此,我认为我需要使用Object::SetPrototype代替,但是我为此所做的每一次尝试都使V8崩溃,创建了一个原型链,其中所有继承的方法都不可见,或者具有相同的有效效果。行为与FunctionTemplate::Inherit情况相同。

在V8中提供继承方法以使本机方法可以添加到超类的公认标准机制是什么?

最佳答案

看来,一旦从Function实例化了实际的FunctionTemplate,对FunctionTemplate的其他更改就不再反映在派生对象中。这样,一旦发生对InheritNewInstance的调用,就不能更改附加到基础FunctionTemplate的方法。

但是,还有另一种方法可以执行此操作:对于每个本机类,都有一个FunctionTemplate,然后实例一个代理Object,以直接在原型链中使用。例如,

v8::Handle<v8::FunctionTemplate> base_tmpl;
v8::Handle<v8::Object> base_proto = base_tmpl->GetFunction()->NewInstance();
v8::Handle<v8::FunctionTemplate> derived_tmpl;
v8::Handle<v8::Object> derived_proto = derived_tmpl->GetFunction()->NewInstance();
derived_proto->SetPrototype(base_proto);

base_proto->Set("methodName", v8::FunctionTemplate::New(...)->GetFunction());


然后,当您要实例化对象时,您可以执行以下操作:

v8::Handle<v8::ObjectTemplate> instance_tmpl;
instance_tmpl->SetInternalFieldCount(1);
v8::Handle<v8::Object> instance = instance_tmpl->NewInstance();
instance->SetInternalField(0, nativeObject);
instance->SetPrototype(derived_proto);


从技术上讲,您只需要实例化代理Object,但仍然可以使用FunctionTemplate来使用其SetClassName(用于调试)和Object::FindInstanceInPrototypeChain(用于在运行时检查类型)其他事情)。

关于c++ - V8继承的FunctionTemplate无法获得对父FunctionTemplate的更新,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28076382/

10-09 13:25