doc: addon: fix object instantiation examples
* Extend examples to show how to handle non-constructor invocation in constructor callback functions. * Fix up examples to initialize member variables at object construction. * Fix up a few naming inconsistencies. Fixes #5701.
This commit is contained in:
parent
9c65387673
commit
51cdce8322
@ -323,12 +323,13 @@ Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`:
|
||||
static void Init(v8::Handle<v8::Object> exports);
|
||||
|
||||
private:
|
||||
MyObject();
|
||||
explicit MyObject(double value = 0);
|
||||
~MyObject();
|
||||
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);
|
||||
double counter_;
|
||||
static v8::Persistent<v8::Function> constructor;
|
||||
double value_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -343,8 +344,13 @@ prototype:
|
||||
|
||||
using namespace v8;
|
||||
|
||||
MyObject::MyObject() {};
|
||||
MyObject::~MyObject() {};
|
||||
Persistent<Function> MyObject::constructor;
|
||||
|
||||
MyObject::MyObject(double value) : value_(value) {
|
||||
}
|
||||
|
||||
MyObject::~MyObject() {
|
||||
}
|
||||
|
||||
void MyObject::Init(Handle<Object> exports) {
|
||||
// Prepare constructor template
|
||||
@ -354,28 +360,34 @@ prototype:
|
||||
// Prototype
|
||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
|
||||
FunctionTemplate::New(PlusOne)->GetFunction());
|
||||
|
||||
Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
|
||||
constructor = Persistent<Function>::New(tpl->GetFunction());
|
||||
exports->Set(String::NewSymbol("MyObject"), constructor);
|
||||
}
|
||||
|
||||
Handle<Value> MyObject::New(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
MyObject* obj = new MyObject();
|
||||
obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
|
||||
obj->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
if (args.IsConstructCall()) {
|
||||
// Invoked as constructor: `new MyObject(...)`
|
||||
double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
|
||||
MyObject* obj = new MyObject(value);
|
||||
obj->Wrap(args.This());
|
||||
return args.This();
|
||||
} else {
|
||||
// Invoked as plain function `MyObject(...)`, turn into construct call.
|
||||
const int argc = 1;
|
||||
Local<Value> argv[argc] = { args[0] };
|
||||
return scope.Close(constructor->NewInstance(argc, argv));
|
||||
}
|
||||
}
|
||||
|
||||
Handle<Value> MyObject::PlusOne(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
|
||||
obj->counter_ += 1;
|
||||
obj->value_ += 1;
|
||||
|
||||
return scope.Close(Number::New(obj->counter_));
|
||||
return scope.Close(Number::New(obj->value_));
|
||||
}
|
||||
|
||||
Test it with:
|
||||
@ -434,13 +446,13 @@ care of instantiating the object (i.e. it does the job of `new` in JavaScript):
|
||||
static v8::Handle<v8::Value> NewInstance(const v8::Arguments& args);
|
||||
|
||||
private:
|
||||
MyObject();
|
||||
explicit MyObject(double value = 0);
|
||||
~MyObject();
|
||||
|
||||
static v8::Persistent<v8::Function> constructor;
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);
|
||||
double counter_;
|
||||
static v8::Persistent<v8::Function> constructor;
|
||||
double value_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -453,11 +465,14 @@ The implementation is similar to the above in `myobject.cc`:
|
||||
|
||||
using namespace v8;
|
||||
|
||||
MyObject::MyObject() {};
|
||||
MyObject::~MyObject() {};
|
||||
|
||||
Persistent<Function> MyObject::constructor;
|
||||
|
||||
MyObject::MyObject(double value) : value_(value) {
|
||||
}
|
||||
|
||||
MyObject::~MyObject() {
|
||||
}
|
||||
|
||||
void MyObject::Init() {
|
||||
// Prepare constructor template
|
||||
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
|
||||
@ -466,18 +481,24 @@ The implementation is similar to the above in `myobject.cc`:
|
||||
// Prototype
|
||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
|
||||
FunctionTemplate::New(PlusOne)->GetFunction());
|
||||
|
||||
constructor = Persistent<Function>::New(tpl->GetFunction());
|
||||
}
|
||||
|
||||
Handle<Value> MyObject::New(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
MyObject* obj = new MyObject();
|
||||
obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
|
||||
obj->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
if (args.IsConstructCall()) {
|
||||
// Invoked as constructor: `new MyObject(...)`
|
||||
double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
|
||||
MyObject* obj = new MyObject(value);
|
||||
obj->Wrap(args.This());
|
||||
return args.This();
|
||||
} else {
|
||||
// Invoked as plain function `MyObject(...)`, turn into construct call.
|
||||
const int argc = 1;
|
||||
Local<Value> argv[argc] = { args[0] };
|
||||
return scope.Close(constructor->NewInstance(argc, argv));
|
||||
}
|
||||
}
|
||||
|
||||
Handle<Value> MyObject::NewInstance(const Arguments& args) {
|
||||
@ -494,9 +515,9 @@ The implementation is similar to the above in `myobject.cc`:
|
||||
HandleScope scope;
|
||||
|
||||
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
|
||||
obj->counter_ += 1;
|
||||
obj->value_ += 1;
|
||||
|
||||
return scope.Close(Number::New(obj->counter_));
|
||||
return scope.Close(Number::New(obj->value_));
|
||||
}
|
||||
|
||||
Test it with:
|
||||
@ -540,7 +561,7 @@ In the following `addon.cc` we introduce a function `add()` that can take on two
|
||||
MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
|
||||
args[1]->ToObject());
|
||||
|
||||
double sum = obj1->Val() + obj2->Val();
|
||||
double sum = obj1->Value() + obj2->Value();
|
||||
return scope.Close(Number::New(sum));
|
||||
}
|
||||
|
||||
@ -569,15 +590,15 @@ can probe private values after unwrapping the object:
|
||||
public:
|
||||
static void Init();
|
||||
static v8::Handle<v8::Value> NewInstance(const v8::Arguments& args);
|
||||
double Val() const { return val_; }
|
||||
double Value() const { return value_; }
|
||||
|
||||
private:
|
||||
MyObject();
|
||||
explicit MyObject(double value = 0);
|
||||
~MyObject();
|
||||
|
||||
static v8::Persistent<v8::Function> constructor;
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments& args);
|
||||
double val_;
|
||||
static v8::Persistent<v8::Function> constructor;
|
||||
double value_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -590,28 +611,37 @@ The implementation of `myobject.cc` is similar as before:
|
||||
|
||||
using namespace v8;
|
||||
|
||||
MyObject::MyObject() {};
|
||||
MyObject::~MyObject() {};
|
||||
|
||||
Persistent<Function> MyObject::constructor;
|
||||
|
||||
MyObject::MyObject(double value) : value_(value) {
|
||||
}
|
||||
|
||||
MyObject::~MyObject() {
|
||||
}
|
||||
|
||||
void MyObject::Init() {
|
||||
// Prepare constructor template
|
||||
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
|
||||
tpl->SetClassName(String::NewSymbol("MyObject"));
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
constructor = Persistent<Function>::New(tpl->GetFunction());
|
||||
}
|
||||
|
||||
Handle<Value> MyObject::New(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
MyObject* obj = new MyObject();
|
||||
obj->val_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
|
||||
obj->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
if (args.IsConstructCall()) {
|
||||
// Invoked as constructor: `new MyObject(...)`
|
||||
double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
|
||||
MyObject* obj = new MyObject(value);
|
||||
obj->Wrap(args.This());
|
||||
return args.This();
|
||||
} else {
|
||||
// Invoked as plain function `MyObject(...)`, turn into construct call.
|
||||
const int argc = 1;
|
||||
Local<Value> argv[argc] = { args[0] };
|
||||
return scope.Close(constructor->NewInstance(argc, argv));
|
||||
}
|
||||
}
|
||||
|
||||
Handle<Value> MyObject::NewInstance(const Arguments& args) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user