diff --git a/doc/class_property_descriptor.md b/doc/class_property_descriptor.md index 7e81358e4..ae2d27e27 100644 --- a/doc/class_property_descriptor.md +++ b/doc/class_property_descriptor.md @@ -1,4 +1,4 @@ -# Class propertry and descriptor +# Class property and descriptor Property descriptor for use with `Napi::ObjectWrap::DefineClass()`. This is different from the standalone `Napi::PropertyDescriptor` because it is @@ -6,6 +6,88 @@ specific to each `Napi::ObjectWrap` subclass. This prevents using descriptors from a different class when defining a new class (preventing the callbacks from having incorrect `this` pointers). +## Example + +```cpp +#include + +class Example : public Napi::ObjectWrap { + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); + Example(const Napi::CallbackInfo &info); + + private: + static Napi::FunctionReference constructor; + double _value; + Napi::Value GetValue(const Napi::CallbackInfo &info); + Napi::Value SetValue(const Napi::CallbackInfo &info); +}; + +Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { + Napi::Function func = DefineClass(env, "Example", { + // Register a class instance accessor with getter and setter functions. + InstanceAccessor("value", &Example::GetValue, &Example::SetValue), + // We can also register a readonly accessor by passing nullptr as the setter. + InstanceAccessor("readOnlyProp", &Example::GetValue, nullptr) + }); + + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); + exports.Set("Example", func); + + return exports; +} + +Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + // ... + Napi::Number value = info[0].As(); + this->_value = value.DoubleValue(); +} + +Napi::FunctionReference Example::constructor; + +Napi::Value Example::GetValue(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + return Napi::Number::New(env, this->_value); +} + +Napi::Value Example::SetValue(const Napi::CallbackInfo &info, const Napi::Value &value) { + Napi::Env env = info.Env(); + // ... + Napi::Number arg = value.As(); + this->_value = arg.DoubleValue(); + return this->GetValue(info); +} + +// Initialize native add-on +Napi::Object Init (Napi::Env env, Napi::Object exports) { + Example::Init(env, exports); + return exports; +} + +// Register and initialize native add-on +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) +``` + +The above code can be used from JavaScript as follows: + +```js +'use strict'; + +const { Example } = require('bindings')('addon'); + +const example = new Example(11); +console.log(example.value); +// It prints 11 +example.value = 19; +console.log(example.value); +// It prints 19 +example.readOnlyProp = 500; +console.log(example.readOnlyProp); +// Unchanged. It prints 19 +``` + ## Methods ### Constructor diff --git a/doc/object_wrap.md b/doc/object_wrap.md index 5bc06c871..31be140f0 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -78,7 +78,7 @@ Napi::Object Init (Napi::Env env, Napi::Object exports) { return exports; } -// Regisgter and initialize native add-on +// Register and initialize native add-on NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) ```