|
1 |
| -# Class propertry and descriptor |
| 1 | +# Class property and descriptor |
2 | 2 |
|
3 | 3 | Property descriptor for use with `Napi::ObjectWrap::DefineClass()`.
|
4 | 4 | This is different from the standalone `Napi::PropertyDescriptor` because it is
|
5 | 5 | specific to each `Napi::ObjectWrap<T>` subclass.
|
6 | 6 | This prevents using descriptors from a different class when defining a new class
|
7 | 7 | (preventing the callbacks from having incorrect `this` pointers).
|
8 | 8 |
|
| 9 | +## Example |
| 10 | + |
| 11 | +```cpp |
| 12 | +#include <napi.h> |
| 13 | + |
| 14 | +class Example : public Napi::ObjectWrap<Example> { |
| 15 | + public: |
| 16 | + static Napi::Object Init(Napi::Env env, Napi::Object exports); |
| 17 | + Example(const Napi::CallbackInfo &info); |
| 18 | + |
| 19 | + private: |
| 20 | + static Napi::FunctionReference constructor; |
| 21 | + double _value; |
| 22 | + Napi::Value GetValue(const Napi::CallbackInfo &info); |
| 23 | + Napi::Value SetValue(const Napi::CallbackInfo &info); |
| 24 | +}; |
| 25 | + |
| 26 | +Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { |
| 27 | + Napi::Function func = DefineClass(env, "Example", { |
| 28 | + // Register a class instance accessor with getter and setter functions. |
| 29 | + InstanceAccessor("value", &Example::GetValue, &Example::SetValue), |
| 30 | + // We can also register a readonly accessor by passing nullptr as the setter. |
| 31 | + InstanceAccessor("readOnlyProp", &Example::GetValue, nullptr) |
| 32 | + }); |
| 33 | + |
| 34 | + constructor = Napi::Persistent(func); |
| 35 | + constructor.SuppressDestruct(); |
| 36 | + exports.Set("Example", func); |
| 37 | + |
| 38 | + return exports; |
| 39 | +} |
| 40 | + |
| 41 | +Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Example>(info) { |
| 42 | + Napi::Env env = info.Env(); |
| 43 | + // ... |
| 44 | + Napi::Number value = info[0].As<Napi::Number>(); |
| 45 | + this->_value = value.DoubleValue(); |
| 46 | +} |
| 47 | + |
| 48 | +Napi::FunctionReference Example::constructor; |
| 49 | + |
| 50 | +Napi::Value Example::GetValue(const Napi::CallbackInfo &info) { |
| 51 | + Napi::Env env = info.Env(); |
| 52 | + return Napi::Number::New(env, this->_value); |
| 53 | +} |
| 54 | + |
| 55 | +Napi::Value Example::SetValue(const Napi::CallbackInfo &info, const Napi::Value &value) { |
| 56 | + Napi::Env env = info.Env(); |
| 57 | + // ... |
| 58 | + Napi::Number arg = value.As<Napi::Number>(); |
| 59 | + this->_value = arg.DoubleValue(); |
| 60 | + return this->GetValue(info); |
| 61 | +} |
| 62 | + |
| 63 | +// Initialize native add-on |
| 64 | +Napi::Object Init (Napi::Env env, Napi::Object exports) { |
| 65 | + Example::Init(env, exports); |
| 66 | + return exports; |
| 67 | +} |
| 68 | + |
| 69 | +// Register and initialize native add-on |
| 70 | +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) |
| 71 | +``` |
| 72 | +
|
| 73 | +The above code can be used from JavaScript as follows: |
| 74 | +
|
| 75 | +```js |
| 76 | +'use strict'; |
| 77 | +
|
| 78 | +const { Example } = require('bindings')('addon'); |
| 79 | +
|
| 80 | +const example = new Example(11); |
| 81 | +console.log(example.value); |
| 82 | +// It prints 11 |
| 83 | +example.value = 19; |
| 84 | +console.log(example.value); |
| 85 | +// It prints 19 |
| 86 | +example.readOnlyProp = 500; |
| 87 | +console.log(example.readOnlyProp); |
| 88 | +// Unchanged. It prints 19 |
| 89 | +``` |
| 90 | + |
9 | 91 | ## Methods
|
10 | 92 |
|
11 | 93 | ### Constructor
|
|
0 commit comments