I am trying to verify that an object passed to a node addon is of the correct type before I unwrap it and start to use it. Here's the solution that I've cobbled together from looking at various sources on the web.
Persistent data:
Nan::Persistent<v8::Function> Event::constructor;
Nan::Persistent<v8::FunctionTemplate> Event::tpl;
The Init function:
void Event::Init(v8::Local<v8::Object> exports) {
Nan::HandleScope scope;
// Prepare constructor template
v8::Local<v8::FunctionTemplate> ctor = Nan::New<v8::FunctionTemplate>(Event::New);
ctor->InstanceTemplate()->SetInternalFieldCount(1);
ctor->SetClassName(Nan::New("Event").ToLocalChecked());
// create a template for checking instances
Local<FunctionTemplate> localTemplate = Nan::New<FunctionTemplate>(Event::New);
localTemplate->SetClassName(Nan::New("Event").ToLocalChecked());
tpl.Reset(localTemplate);
// Statics
Nan::SetMethod(ctor, "x", Event::X);
// Prototype
Nan::SetPrototypeMethod(ctor, "addInfo", Event::addInfo);
Nan::SetPrototypeMethod(ctor, "toString", Event::toString);
constructor.Reset(ctor->GetFunction());
Nan::Set(exports, Nan::New("Event").ToLocalChecked(), ctor->GetFunction());
}
And where I attempt to use it:
if (Nan::New(tpl)->HasInstance(info[0])) {
message = "it is an Event instance";
}
The problem is that the HasInstance()
never returns true.
The JavaScript code is basically
let e = new Event()
fn(e) // where fn performs the HasInstance() test.
There is no need to make a second FunctionTemplate
. The one you've set on the exports (ctor
) is the one that gets used when you call new Event()
in JS, while the second one (localTemplate
) gets saved to Event::tpl
and is the one from which the HasInstance()
call gets made. They're different FunctionTemplate
s, so the HasInstance()
call returns false
.
Instead of this:
...
Local<FunctionTemplate> localTemplate = Nan::New<FunctionTemplate>(Event::New);
localTemplate->SetClassName(Nan::New("Event").ToLocalChecked());
tpl.Reset(localTemplate);
...
just try this:
...
tpl.Reset(ctor);
...