C++ 从构造函数中获取原型,而无需在v8中创建实例
我正在编写一个导出对象构造函数的v8节点扩展,如中所示。有些函数将其他类的实例作为参数,因此我想检查这些参数的类型,类似于所建议的。它建议的一件事是将对象的原型与来自临时实例的已知正确原型进行比较,如 当前,如果我在节点中运行以下代码(在构建加载项之后),我会得到类型错误:C++ 从构造函数中获取原型,而无需在v8中创建实例,c++,node.js,v8,C++,Node.js,V8,我正在编写一个导出对象构造函数的v8节点扩展,如中所示。有些函数将其他类的实例作为参数,因此我想检查这些参数的类型,类似于所建议的。它建议的一件事是将对象的原型与来自临时实例的已知正确原型进行比较,如 当前,如果我在节点中运行以下代码(在构建加载项之后),我会得到类型错误: var hello=require('./build/Release/hello'); var obj=new hello.MyObject(); obj.typeTest(); 有没有办法设置MyObject::prot
var hello=require('./build/Release/hello');
var obj=new hello.MyObject();
obj.typeTest();
有没有办法设置
MyObject::prototype
,这样我就不会在不构建MyObject
的临时实例的情况下出现错误?您不能在第一次创建对象时设置静态原型值,而不是在Init
中设置吗?大概是这样的:
class MyObject : public node::ObjectWrap {
// ... as before ...
};
Persistent<Function> MyObject::constructor;
Persistent<Value> MyObject::prototype;
void MyObject::Init(Handle<Object> exports)
// ... as before but without setting prototype ...
}
Handle<Value> MyObject::New(const Arguments& args) {
HandleScope scope;
if (args.IsConstructCall()) {
MyObject *obj = new MyObject();
obj->Wrap(args.This());
prototype = Persistent<Value>::New(args.This()->GetPrototype());
return args.This();
} else {
return scope.Close(constructor->NewInstance());
}
}
Handle<Value> MyObject::TypeTest(const Arguments& args) {
HandleScope scope;
if(args.This()->GetPrototype() != prototype) {
return ThrowException(Exception::TypeError(
String::New("This should not happen")));
}
return Undefined();
}
NODE_MODULE(hello, MyObject::Init);
类MyObject:public节点::ObjectWrap{
//…和以前一样。。。
};
持久MyObject::构造函数;
持久性MyObject::原型;
void MyObject::Init(句柄导出)
// ... 和以前一样,但没有设置原型。。。
}
句柄MyObject::新建(常量参数和参数){
手镜镜;
if(args.IsConstructCall()){
MyObject*obj=新的MyObject();
obj->Wrap(args.This());
prototype=Persistent::New(args.This()->GetPrototype());
返回args.This();
}否则{
返回scope.Close(构造函数->NewInstance());
}
}
Handle MyObject::TypeTest(常量参数和参数){
手镜镜;
if(args.This()->GetPrototype()!=prototype){
返回ThroweException(异常::TypeError(
字符串::New(“这不应该发生”);
}
返回未定义();
}
节点_模块(你好,MyObject::Init);
我现在觉得有点傻。这似乎正是我想要的。一个小的编辑:新行应该是prototype=Persistent::new(args.This()->GetPrototype()
。谢谢你建议的编辑。我现在已经合并了它。但是,对于像这样的小事情,通常值得自己去修改代码。我通常认为在别人的帖子中编辑代码是不好的形式。
void MyObject::Init(Handle<Object> exports) {
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->SetClassName(String::NewSymbol("MyObject"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prototype
tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
FunctionTemplate::New(PlusOne)->GetFunction());
constructor = Persistent<Function>::New(tpl->GetFunction());
exports->Set(String::NewSymbol("MyObject"), constructor);
}
#include <node.h>
#include <v8.h>
using namespace v8;
class MyObject : public node::ObjectWrap {
public:
static void Init(Handle<Object> exports);
static Persistent<Value> prototype;
private:
static Handle<Value> New(const v8::Arguments& args);
static Handle<Value> TypeTest(const v8::Arguments& args);
static Persistent<Function> constructor;
};
Persistent<Function> MyObject::constructor;
Persistent<Value> MyObject::prototype;
void MyObject::Init(Handle<Object> exports) {
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->SetClassName(String::NewSymbol("MyObject"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->PrototypeTemplate()->Set(
String::NewSymbol("typeTest"),
FunctionTemplate::New(TypeTest)->GetFunction());
constructor = Persistent<Function>::New(tpl->GetFunction());
prototype = Persistent<Value>::New(tpl->PrototypeTemplate()->NewInstance());
exports->Set(String::NewSymbol("MyObject"),
constructor);
}
Handle<Value> MyObject::New(const Arguments& args) {
HandleScope scope;
if (args.IsConstructCall()) {
MyObject *obj = new MyObject();
obj->Wrap(args.This());
return args.This();
} else {
return scope.Close(constructor->NewInstance());
}
}
Handle<Value> MyObject::TypeTest(const Arguments& args) {
HandleScope scope;
if(args.This()->GetPrototype() != prototype) {
return ThrowException(Exception::TypeError(
String::New("This should not happen")));
}
return Undefined();
}
NODE_MODULE(hello, MyObject::Init);
class MyObject : public node::ObjectWrap {
// ... as before ...
};
Persistent<Function> MyObject::constructor;
Persistent<Value> MyObject::prototype;
void MyObject::Init(Handle<Object> exports)
// ... as before but without setting prototype ...
}
Handle<Value> MyObject::New(const Arguments& args) {
HandleScope scope;
if (args.IsConstructCall()) {
MyObject *obj = new MyObject();
obj->Wrap(args.This());
prototype = Persistent<Value>::New(args.This()->GetPrototype());
return args.This();
} else {
return scope.Close(constructor->NewInstance());
}
}
Handle<Value> MyObject::TypeTest(const Arguments& args) {
HandleScope scope;
if(args.This()->GetPrototype() != prototype) {
return ThrowException(Exception::TypeError(
String::New("This should not happen")));
}
return Undefined();
}
NODE_MODULE(hello, MyObject::Init);