1# Object Wrap
2
3Class `Napi::ObjectWrap<T>` inherits from class [`Napi::InstanceWrap<T>`][].
4
5The `Napi::ObjectWrap<T>` class is used to bind the lifetime of C++ code to a
6JavaScript object. Once bound, each time an instance of the JavaScript object
7is created, an instance of the C++ class will also be created. When a method
8is called on the JavaScript object which is defined as an InstanceMethod, the
9corresponding C++ method on the wrapped C++ class will be invoked.
10
11In order to create a wrapper it's necessary to extend the
12`Napi::ObjectWrap<T>` class which contains all the plumbing to connect
13JavaScript code with a C++ object. Classes extending `Napi::ObjectWrap` can be
14instantiated from JavaScript using the **new** operator, and their methods can
15be directly invoked from JavaScript. The **wrap** word refers to a way of
16grouping methods and state of the class because it will be necessary write
17custom code to bridge each of your C++ class methods.
18
19**Caution:** When the JavaScript object is garbage collected, the call to the
20C++ destructor may be deferred until a later time. Within that period,
21`Value()` will return an empty value.
22
23## Example
24
25```cpp
26#include <napi.h>
27
28class Example : public Napi::ObjectWrap<Example> {
29  public:
30    static Napi::Object Init(Napi::Env env, Napi::Object exports);
31    Example(const Napi::CallbackInfo& info);
32    static Napi::Value CreateNewItem(const Napi::CallbackInfo& info);
33
34  private:
35    double _value;
36    Napi::Value GetValue(const Napi::CallbackInfo& info);
37    Napi::Value SetValue(const Napi::CallbackInfo& info);
38};
39
40Napi::Object Example::Init(Napi::Env env, Napi::Object exports) {
41    // This method is used to hook the accessor and method callbacks
42    Napi::Function func = DefineClass(env, "Example", {
43        InstanceMethod<&Example::GetValue>("GetValue", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
44        InstanceMethod<&Example::SetValue>("SetValue", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
45        StaticMethod<&Example::CreateNewItem>("CreateNewItem", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
46    });
47
48    Napi::FunctionReference* constructor = new Napi::FunctionReference();
49
50    // Create a persistent reference to the class constructor. This will allow
51    // a function called on a class prototype and a function
52    // called on instance of a class to be distinguished from each other.
53    *constructor = Napi::Persistent(func);
54    exports.Set("Example", func);
55
56    // Store the constructor as the add-on instance data. This will allow this
57    // add-on to support multiple instances of itself running on multiple worker
58    // threads, as well as multiple instances of itself running in different
59    // contexts on the same thread.
60    //
61    // By default, the value set on the environment here will be destroyed when
62    // the add-on is unloaded using the `delete` operator, but it is also
63    // possible to supply a custom deleter.
64    env.SetInstanceData<Napi::FunctionReference>(constructor);
65
66    return exports;
67}
68
69Example::Example(const Napi::CallbackInfo& info) :
70    Napi::ObjectWrap<Example>(info) {
71  Napi::Env env = info.Env();
72  // ...
73  Napi::Number value = info[0].As<Napi::Number>();
74  this->_value = value.DoubleValue();
75}
76
77Napi::Value Example::GetValue(const Napi::CallbackInfo& info){
78    Napi::Env env = info.Env();
79    return Napi::Number::New(env, this->_value);
80}
81
82Napi::Value Example::SetValue(const Napi::CallbackInfo& info){
83    Napi::Env env = info.Env();
84    // ...
85    Napi::Number value = info[0].As<Napi::Number>();
86    this->_value = value.DoubleValue();
87    return this->GetValue(info);
88}
89
90// Initialize native add-on
91Napi::Object Init (Napi::Env env, Napi::Object exports) {
92    Example::Init(env, exports);
93    return exports;
94}
95
96// Create a new item using the constructor stored during Init.
97Napi::Value Example::CreateNewItem(const Napi::CallbackInfo& info) {
98  // Retrieve the instance data we stored during `Init()`. We only stored the
99  // constructor there, so we retrieve it here to create a new instance of the
100  // JS class the constructor represents.
101  Napi::FunctionReference* constructor =
102      info.Env().GetInstanceData<Napi::FunctionReference>();
103  return constructor->New({ Napi::Number::New(info.Env(), 42) });
104}
105
106// Register and initialize native add-on
107NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
108```
109
110The above code can be used from JavaScript as follows:
111
112```js
113'use strict'
114
115const { Example } = require('bindings')('addon')
116
117const example = new Example(11)
118console.log(example.GetValue())
119// It prints 11
120example.SetValue(19)
121console.log(example.GetValue());
122// It prints 19
123```
124
125At initialization time, the `Napi::ObjectWrap::DefineClass()` method must be
126used to hook up the accessor and method callbacks. It takes a list of property
127descriptors, which can be constructed via the various static methods on the base
128class.
129
130When JavaScript code invokes the constructor, the constructor callback will
131create a new C++ instance and "wrap" it into the newly created JavaScript
132object.
133
134When JavaScript code invokes a method or a property accessor on the class the
135corresponding C++ callback function will be executed.
136
137For a wrapped object it could be difficult to distinguish between a function
138called on a class prototype and a function called on instance of a class.
139Therefore it is good practice to save a persistent reference to the class
140constructor. This allows the two cases to be distinguished from each other by
141checking the this object against the class constructor.
142
143## Methods
144
145### Constructor
146
147Creates a new instance of a JavaScript object that wraps native instance.
148
149```cpp
150Napi::ObjectWrap(const Napi::CallbackInfo& callbackInfo);
151```
152
153- `[in] callbackInfo`: The object representing the components of the JavaScript
154request being made.
155
156### Unwrap
157
158Retrieves a native instance wrapped in a JavaScript object.
159
160```cpp
161static T* Napi::ObjectWrap::Unwrap(Napi::Object wrapper);
162```
163
164* `[in] wrapper`: The JavaScript object that wraps the native instance.
165
166Returns a native instance wrapped in a JavaScript object. Given the
167`Napi::Object`, this allows a method to get a pointer to the wrapped
168C++ object and then reference fields, call methods, etc. within that class.
169In many cases calling Unwrap is not required, as methods can
170use the `this` field for ObjectWrap when running in a method on a
171class that extends ObjectWrap.
172
173### DefineClass
174
175Defnines a JavaScript class with constructor, static and instance properties and
176methods.
177
178```cpp
179static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env,
180                    const char* utf8name,
181                    const std::initializer_list<PropertyDescriptor>& properties,
182                    void* data = nullptr);
183```
184
185* `[in] env`: The environment in which to construct a JavaScript class.
186* `[in] utf8name`: Null-terminated string that represents the name of the
187JavaScript constructor function.
188* `[in] properties`: Initializer list of class property descriptor describing
189static and instance properties and methods of the class.
190See: [`Class property and descriptor`](class_property_descriptor.md).
191* `[in] data`: User-provided data passed to the constructor callback as `data`
192property of the `Napi::CallbackInfo`.
193
194Returns a `Napi::Function` representing the constructor function for the class.
195
196### DefineClass
197
198Defnines a JavaScript class with constructor, static and instance properties and
199methods.
200
201```cpp
202static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env,
203                            const char* utf8name,
204                            const std::vector<PropertyDescriptor>& properties,
205                            void* data = nullptr);
206```
207
208* `[in] env`: The environment in which to construct a JavaScript class.
209* `[in] utf8name`: Null-terminated string that represents the name of the
210JavaScript constructor function.
211* `[in] properties`: Vector of class property descriptor describing static and
212instance properties and methods of the class.
213See: [`Class property and descriptor`](class_property_descriptor.md).
214* `[in] data`: User-provided data passed to the constructor callback as `data`
215property of the `Napi::CallbackInfo`.
216
217Returns a `Napi::Function` representing the constructor function for the class.
218
219### OnCalledAsFunction
220
221Provides an opportunity to customize the behavior when a `Napi::ObjectWrap<T>`
222class is called from JavaScript as a function (without the **new** operator).
223
224The default behavior in this scenario is to throw a `Napi::TypeError` with the
225message `Class constructors cannot be invoked without 'new'`.  Define this
226public method on your derived class to override that behavior.
227
228For example, you could internally re-call the JavaScript contstructor _with_
229the **new** operator (via
230`Napi::Function::New(const std::vector<napi_value> &args)`), and return the
231resulting object.  Or you might do something else entirely, such as the way
232[`Date()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#constructor)
233produces a string when called as a function.
234
235```cpp
236static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
237```
238
239- `[in] callbackInfo`: The object representing the components of the JavaScript
240request being made.
241
242### Finalize
243
244Provides an opportunity to run cleanup code that requires access to the
245`Napi::Env` before the wrapped native object instance is freed.  Override to
246implement.
247
248```cpp
249virtual void Finalize(Napi::Env env);
250```
251
252- `[in] env`: `Napi::Env`.
253
254### StaticMethod
255
256Creates property descriptor that represents a static method of a JavaScript
257class.
258
259```cpp
260static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(
261                             const char* utf8name,
262                             StaticVoidMethodCallback method,
263                             napi_property_attributes attributes = napi_default,
264                             void* data = nullptr);
265```
266
267- `[in] utf8name`: Null-terminated string that represents the name of a static
268method for the class.
269- `[in] method`: The native function that represents a static method of a
270JavaScript class.
271- `[in] attributes`: The attributes associated with a particular property.
272One or more of `napi_property_attributes`.
273- `[in] data`: User-provided data passed into method when it is invoked.
274
275Returns `Napi::PropertyDescriptor` object that represents the static method of a
276JavaScript class.
277
278### StaticMethod
279
280Creates property descriptor that represents a static method of a JavaScript
281class.
282
283```cpp
284static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(
285                             const char* utf8name,
286                             StaticMethodCallback method,
287                             napi_property_attributes attributes = napi_default,
288                             void* data = nullptr);
289```
290
291- `[in] utf8name`: Null-terminated string that represents the name of a static
292method for the class.
293- `[in] method`: The native function that represents a static method of a
294JavaScript class.
295- `[in] attributes`: The attributes associated with a particular property.
296One or more of `napi_property_attributes`.
297- `[in] data`: User-provided data passed into method when it is invoked.
298
299Returns `Napi::PropertyDescriptor` object that represents a static method of a
300JavaScript class.
301
302### StaticMethod
303
304Creates property descriptor that represents a static method of a JavaScript
305class.
306
307```cpp
308static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name,
309                             StaticVoidMethodCallback method,
310                             napi_property_attributes attributes = napi_default,
311                             void* data = nullptr);
312```
313
314- `[in] name`: Napi::Symbol that represents the name of a static
315method for the class.
316- `[in] method`: The native function that represents a static method of a
317JavaScript class.
318- `[in] attributes`: The attributes associated with a particular property.
319One or more of `napi_property_attributes`.
320- `[in] data`: User-provided data passed into method when it is invoked.
321
322Returns `Napi::PropertyDescriptor` object that represents the static method of a
323JavaScript class.
324
325### StaticMethod
326
327Creates property descriptor that represents a static method of a JavaScript
328class.
329
330```cpp
331static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name,
332                             StaticMethodCallback method,
333                             napi_property_attributes attributes = napi_default,
334                             void* data = nullptr);
335```
336
337method for the class.
338- `[in] name`: Napi::Symbol that represents the name of a static.
339- `[in] method`: The native function that represents a static method of a
340JavaScript class.
341- `[in] attributes`: The attributes associated with a particular property.
342One or more of `napi_property_attributes`.
343- `[in] data`: User-provided data passed into method when it is invoked.
344
345Returns `Napi::PropertyDescriptor` object that represents a static method of a
346JavaScript class.
347
348### StaticMethod
349
350Creates property descriptor that represents a static method of a JavaScript
351class.
352
353```cpp
354template <StaticVoidMethodCallback method>
355static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(
356                             const char* utf8name,
357                             napi_property_attributes attributes = napi_default,
358                             void* data = nullptr);
359```
360
361- `[in] method`: The native function that represents a static method of a
362JavaScript class. This function returns nothing.
363- `[in] utf8name`: Null-terminated string that represents the name of a static
364method for the class.
365- `[in] attributes`: The attributes associated with a particular property.
366One or more of `napi_property_attributes`.
367- `[in] data`: User-provided data passed into method when it is invoked.
368
369Returns `Napi::PropertyDescriptor` object that represents the static method of a
370JavaScript class.
371
372### StaticMethod
373
374Creates property descriptor that represents a static method of a JavaScript
375class.
376
377```cpp
378template <StaticMethodCallback method>
379static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(
380                             const char* utf8name,
381                             napi_property_attributes attributes = napi_default,
382                             void* data = nullptr);
383```
384
385- `[in] method`: The native function that represents a static method of a
386JavaScript class.
387- `[in] utf8name`: Null-terminated string that represents the name of a static
388method for the class.
389- `[in] attributes`: The attributes associated with a particular property.
390One or more of `napi_property_attributes`.
391- `[in] data`: User-provided data passed into method when it is invoked.
392
393Returns `Napi::PropertyDescriptor` object that represents a static method of a
394JavaScript class.
395
396### StaticMethod
397
398Creates property descriptor that represents a static method of a JavaScript
399class.
400
401```cpp
402template <StaticVoidMethodCallback method>
403static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name,
404                             napi_property_attributes attributes = napi_default,
405                             void* data = nullptr);
406```
407
408- `[in] method`: The native function that represents a static method of a
409JavaScript class.
410- `[in] name`: Napi::Symbol that represents the name of a static
411method for the class.
412- `[in] attributes`: The attributes associated with a particular property.
413One or more of `napi_property_attributes`.
414- `[in] data`: User-provided data passed into method when it is invoked.
415
416Returns `Napi::PropertyDescriptor` object that represents the static method of a
417JavaScript class.
418
419### StaticMethod
420
421Creates property descriptor that represents a static method of a JavaScript
422class.
423
424```cpp
425template <StaticMethodCallback method>
426static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name,
427                             napi_property_attributes attributes = napi_default,
428                             void* data = nullptr);
429```
430
431- `[in] method`: The native function that represents a static method of a
432JavaScript class.
433- `[in] name`: Napi::Symbol that represents the name of a static.
434- `[in] attributes`: The attributes associated with a particular property.
435One or more of `napi_property_attributes`.
436- `[in] data`: User-provided data passed into method when it is invoked.
437
438Returns `Napi::PropertyDescriptor` object that represents a static method of a
439JavaScript class.
440
441### StaticAccessor
442
443Creates property descriptor that represents a static accessor property of a
444JavaScript class.
445
446```cpp
447static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(
448                             const char* utf8name,
449                             StaticGetterCallback getter,
450                             StaticSetterCallback setter,
451                             napi_property_attributes attributes = napi_default,
452                             void* data = nullptr);
453```
454
455- `[in] utf8name`: Null-terminated string that represents the name of a static
456accessor property for the class.
457- `[in] getter`: The native function to call when a get access to the property
458of a JavaScript class is performed.
459- `[in] setter`: The native function to call when a set access to the property
460of a JavaScript class is performed.
461- `[in] attributes`: The attributes associated with a particular property.
462One or more of `napi_property_attributes`.
463- `[in] data`: User-provided data passed into getter or setter when
464is invoked.
465
466Returns `Napi::PropertyDescriptor` object that represents a static accessor
467property of a JavaScript class.
468
469### StaticAccessor
470
471Creates property descriptor that represents a static accessor property of a
472JavaScript class.
473
474```cpp
475static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(Symbol name,
476                             StaticGetterCallback getter,
477                             StaticSetterCallback setter,
478                             napi_property_attributes attributes = napi_default,
479                             void* data = nullptr);
480```
481
482- `[in] name`: Napi::Symbol that represents the name of a static accessor.
483- `[in] getter`: The native function to call when a get access to the property
484of a JavaScript class is performed.
485- `[in] setter`: The native function to call when a set access to the property
486of a JavaScript class is performed.
487- `[in] attributes`: The attributes associated with a particular property.
488One or more of `napi_property_attributes`.
489- `[in] data`: User-provided data passed into getter or setter when
490is invoked.
491
492Returns `Napi::PropertyDescriptor` object that represents a static accessor
493property of a JavaScript class.
494
495### StaticAccessor
496
497Creates property descriptor that represents a static accessor property of a
498JavaScript class.
499
500```cpp
501template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr>
502static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(
503                             const char* utf8name,
504                             napi_property_attributes attributes = napi_default,
505                             void* data = nullptr);
506```
507
508- `[in] getter`: The native function to call when a get access to the property
509of a JavaScript class is performed.
510- `[in] setter`: The native function to call when a set access to the property
511of a JavaScript class is performed.
512- `[in] utf8name`: Null-terminated string that represents the name of a static
513accessor property for the class.
514- `[in] attributes`: The attributes associated with a particular property.
515One or more of `napi_property_attributes`.
516- `[in] data`: User-provided data passed into getter or setter when
517is invoked.
518
519Returns `Napi::PropertyDescriptor` object that represents a static accessor
520property of a JavaScript class.
521
522### StaticAccessor
523
524Creates property descriptor that represents a static accessor property of a
525JavaScript class.
526
527```cpp
528template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr>
529static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(Symbol name,
530                             napi_property_attributes attributes = napi_default,
531                             void* data = nullptr);
532```
533
534- `[in] getter`: The native function to call when a get access to the property
535of a JavaScript class is performed.
536- `[in] setter`: The native function to call when a set access to the property
537of a JavaScript class is performed.
538- `[in] name`: Napi::Symbol that represents the name of a static accessor.
539- `[in] attributes`: The attributes associated with a particular property.
540One or more of `napi_property_attributes`.
541- `[in] data`: User-provided data passed into getter or setter when
542is invoked.
543
544Returns `Napi::PropertyDescriptor` object that represents a static accessor
545property of a JavaScript class.
546
547### StaticValue
548
549Creates property descriptor that represents an static value property of a
550JavaScript class.
551```cpp
552static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(
553                            const char* utf8name,
554                            Napi::Value value,
555                            napi_property_attributes attributes = napi_default);
556```
557
558- `[in] utf8name`: Null-terminated string that represents the name of the static
559property.
560- `[in] value`: The value that's retrieved by a get access of the property.
561- `[in] attributes`: The attributes to be associated with the property in
562addition to the napi_static attribute.  One or more of
563`napi_property_attributes`.
564
565Returns `Napi::PropertyDescriptor` object that represents an static value
566property of a JavaScript class
567
568### StaticValue
569
570Creates property descriptor that represents an static value property of a
571JavaScript class.
572```cpp
573static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(Symbol name,
574                            Napi::Value value,
575                            napi_property_attributes attributes = napi_default);
576```
577
578- `[in] name`: The `Napi::Symbol` object whose value is used to identify the
579name of the static property.
580- `[in] value`: The value that's retrieved by a get access of the property.
581- `[in] attributes`: The attributes to be associated with the property in
582addition to the napi_static attribute.  One or more of
583`napi_property_attributes`.
584
585Returns `Napi::PropertyDescriptor` object that represents an static value
586property of a JavaScript class
587
588[`Napi::InstanceWrap<T>`]: ./instance_wrap.md
589