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