news 2026/8/26 19:28:13

Object Wrap

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Object Wrap

对象包装器(Object Wrap)

Napi::ObjectWrap<T>类继承自Napi::InstanceWrap<T>类。

Napi::ObjectWrap<T>类用于将 C++ 代码的生命周期绑定到 JavaScript 对象上。绑定完成后,每当创建一个 JavaScript 对象实例时,对应的 C++ 类实例也会被创建;当调用 JavaScript 对象上定义为InstanceMethod的方法时,被包装的 C++ 类中对应的 C++ 方法会被触发执行。

要实现包装器,必须继承Napi::ObjectWrap<T>类 —— 该类包含了将 JavaScript 代码与 C++ 对象连接起来的所有底层逻辑。继承Napi::ObjectWrap的类可在 JavaScript 中通过new运算符实例化,其方法也可直接从 JavaScript 中调用。「包装(wrap)」一词指的是将类的方法和状态整合在一起的方式,因为你需要编写自定义代码来桥接 C++ 类的每个方法。

⚠️ 注意:当 JavaScript 对象被垃圾回收时,C++ 析构函数的调用可能会延迟到后续某个时间点。在此期间,Value()方法会返回空值。

示例

#include <napi.h> class Example : public Napi::ObjectWrap<Example> { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); Example(const Napi::CallbackInfo& info); static Napi::Value CreateNewItem(const Napi::CallbackInfo& info); private: 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", { InstanceMethod<&Example::GetValue>("GetValue", static_cast<napi_property_attributes>(napi_writable | napi_configurable)), InstanceMethod<&Example::SetValue>("SetValue", static_cast<napi_property_attributes>(napi_writable | napi_configurable)), StaticMethod<&Example::CreateNewItem>("CreateNewItem", static_cast<napi_property_attributes>(napi_writable | napi_configurable)), }); Napi::FunctionReference* constructor = new Napi::FunctionReference(); // 为类构造函数创建持久引用。这能区分 // 调用类原型上的函数和调用类实例上的函数这两种场景。 *constructor = Napi::Persistent(func); exports.Set("Example", func); // 将构造函数存储为插件实例数据。这能让该插件 // 支持在多个工作线程上运行多个实例,也支持在同一线程的不同上下文 // 中运行多个实例。 // // 默认情况下,此处设置在环境中的值会在插件卸载时通过 `delete` 运算符销毁, // 但也可以自定义销毁器(deleter)。 env.SetInstanceData<Napi::FunctionReference>(constructor); return exports; } Example::Example(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Example>(info) { Napi::Env env = info.Env(); // ... Napi::Number value = info[0].As<Napi::Number>(); this->_value = value.DoubleValue(); } 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){ Napi::Env env = info.Env(); // ... Napi::Number value = info[0].As<Napi::Number>(); this->_value = value.DoubleValue(); return this->GetValue(info); } // 初始化原生插件 Napi::Object Init (Napi::Env env, Napi::Object exports) { Example::Init(env, exports); return exports; } // 使用 Init 阶段存储的构造函数创建新实例 Napi::Value Example::CreateNewItem(const Napi::CallbackInfo& info) { // 获取在 `Init()` 阶段存储的实例数据。我们仅在其中存储了构造函数, // 因此此处取出它,用于创建该构造函数对应的 JS 类的新实例。 Napi::FunctionReference* constructor = info.Env().GetInstanceData<Napi::FunctionReference>(); return constructor->New({ Napi::Number::New(info.Env(), 42) }); } // 注册并初始化原生插件 NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

上述代码可在 JavaScript 中按如下方式使用:

'use strict' const { Example } = require('bindings')('addon') const example = new Example(11) console.log(example.GetValue()) // 输出 11 example.SetValue(19) console.log(example.GetValue()); // 输出 19

初始化阶段必须调用Napi::ObjectWrap::DefineClass()方法来关联访问器和方法的回调函数。该方法接收一组属性描述符,这些描述符可通过基类的各类静态方法构造。

当 JavaScript 代码调用构造函数时,构造函数回调会创建一个新的 C++ 实例,并将其「包装」到新创建的 JavaScript 对象中。

当 JavaScript 代码调用类上的方法或属性访问器时,对应的 C++ 回调函数会被执行。

对于包装对象,可能难以区分「调用类原型上的函数」和「调用类实例上的函数」这两种场景。因此,最佳实践是保存类构造函数的持久引用 —— 通过检查this对象与类构造函数的关系,可区分这两种场景。

方法

构造函数(Constructor)

创建一个包装了原生实例的 JavaScript 对象新实例。

Napi::ObjectWrap(const Napi::CallbackInfo& callbackInfo);
  • [in] callbackInfo:表示当前 JavaScript 请求各组成部分的对象。

Unwrap

提取被包装在 JavaScript 对象中的原生实例。

static T* Napi::ObjectWrap::Unwrap(Napi::Object wrapper);
  • [in] wrapper:包装了原生实例的 JavaScript 对象。

返回被包装在 JavaScript 对象中的原生实例。传入Napi::Object后,该方法能获取被包装的 C++ 对象指针,进而访问该类内的字段、调用方法等。多数场景下无需调用Unwrap—— 在继承ObjectWrap的类的方法中,可直接使用this指针访问包装对象。

DefineClass

定义一个包含构造函数、静态属性、实例属性、静态方法、实例方法的 JavaScript 类。

static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, const char* utf8name, const std::initializer_list<PropertyDescriptor>& properties, void* data = nullptr);
  • [in] env:用于构造 JavaScript 类的运行环境。
  • [in] utf8name:以空字符结尾的字符串,表示 JavaScript 构造函数的名称。
  • [in] properties:用于描述类的静态 / 实例属性和方法的属性描述符初始化列表(详见:类属性与描述符)。
  • [in] data:用户提供的数据,会作为Napi::CallbackInfodata属性传入构造函数回调。

返回表示该类构造函数的Napi::Function对象。

DefineClass

定义一个包含构造函数、静态属性、实例属性、静态方法、实例方法的 JavaScript 类。

static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, const char* utf8name, const std::vector<PropertyDescriptor>& properties, void* data = nullptr);
  • [in] env:用于构造 JavaScript 类的运行环境。
  • [in] utf8name:以空字符结尾的字符串,表示 JavaScript 构造函数的名称。
  • [in] properties:用于描述类的静态 / 实例属性和方法的属性描述符向量(详见:类属性与描述符)。
  • [in] data:用户提供的数据,会作为Napi::CallbackInfodata属性传入构造函数回调。

返回表示该类构造函数的Napi::Function对象。

OnCalledAsFunction

自定义Napi::ObjectWrap<T>类在 JavaScript 中被当作函数调用(未使用new运算符)时的行为。

该场景下的默认行为是抛出一个Napi::TypeError,错误信息为「Class constructors cannot be invoked without 'new'(类构造函数必须使用 'new' 调用)」。在派生类中定义该公有方法可覆盖此默认行为。

例如,你可在内部通过new运算符重新调用 JavaScript 构造函数(通过Napi::Function::New(const std::vector<napi_value> &args))并返回结果对象;也可实现完全自定义的逻辑(如Date()作为函数调用时返回字符串)。

static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
  • [in] callbackInfo:表示当前 JavaScript 请求各组成部分的对象。

Finalize

提供执行仅依赖基础 Node API 的清理代码的时机(如有需要)。可重写该方法实现自定义逻辑(详见「终结化(Finalization)」)。

virtual void Finalize(Napi::BasicEnv env);
  • [in] envNapi::Env运行环境。

Finalize

提供执行依赖非基础 Node API 的清理代码的时机。可重写该方法实现自定义逻辑。

⚠️ 注意:定义该方法会导致底层T*数据的销毁操作推迟到垃圾回收周期结束后。由于Napi::Env可访问非基础 Node API,其逻辑无法与垃圾回收器在同一个事件循环周期(tick)中执行。

virtual void Finalize(Napi::Env env);
  • [in] envNapi::Env运行环境。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, StaticVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, StaticMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, StaticVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, StaticMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticVoidMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数(无返回值)。
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticVoidMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor( const char* utf8name, StaticGetterCallback getter, StaticSetterCallback setter, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] utf8name:以空字符结尾的字符串,表示类的静态访问器属性名称。
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(Symbol name, StaticGetterCallback getter, StaticSetterCallback setter, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] name:表示静态访问器名称的Napi::Symbol对象。
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor( const char* utf8name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数(默认值为nullptr)。
  • [in] utf8name:以空字符结尾的字符串,表示类的静态访问器属性名称。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(Symbol name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数(默认值为nullptr)。
  • [in] name:表示静态访问器名称的Napi::Symbol对象。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticValue

创建表示 JavaScript 类静态值属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue( const char* utf8name, Napi::Value value, napi_property_attributes attributes = napi_default);
  • [in] utf8name:以空字符结尾的字符串,表示静态属性的名称。
  • [in] value:读取(get)该属性时返回的值。
  • [in] attributes:除napi_static外,与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。

返回表示 JavaScript 类静态值属性的Napi::PropertyDescriptor对象。

StaticValue

创建表示 JavaScript 类静态值属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(Symbol name, Napi::Value value, napi_property_attributes attributes = napi_default);
  • [in] nameNapi::Symbol对象,其值用于标识静态属性的名称。
  • [in] value:读取(get)该属性时返回的值。
  • [in] attributes:除napi_static外,与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。

返回表示 JavaScript 类静态值属性的Napi::PropertyDescriptor对象。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 19:42:59

终极指南:5分钟快速上手Turing智能屏幕Python系统监控!

终极指南&#xff1a;5分钟快速上手Turing智能屏幕Python系统监控&#xff01; 【免费下载链接】turing-smart-screen-python Unofficial Python system monitor and library for small IPS USB-C displays like Turing Smart Screen or XuanFang 项目地址: https://gitcode.…

作者头像 李华
网站建设 2026/8/19 15:35:58

液压元件图形符号实用指南:从入门到精通

液压元件图形符号实用指南&#xff1a;从入门到精通 【免费下载链接】常用液压元件图形符号资源介绍 本开源项目提供了一份详尽的“常用液压元件图形符号”PDF资源&#xff0c;涵盖了液压泵、液压马达、液压缸等核心元件的图形符号&#xff0c;以及机械控制装置、压力控制阀等关…

作者头像 李华
网站建设 2026/8/24 8:25:31

快速修复inshellisense智能提示:医生工具is doctor实战指南

快速修复inshellisense智能提示&#xff1a;医生工具is doctor实战指南 【免费下载链接】inshellisense microsoft/inshellisense: 是 Visual Studio Code 的一个扩展&#xff0c;可以在集成终端中提供 IntelliSense 功能。适合对 Visual Studio Code、终端和想要在终端中使用 …

作者头像 李华
网站建设 2026/8/19 15:48:09

终极微信跳一跳攻略:Auto.js自动化工具全揭秘

终极微信跳一跳攻略&#xff1a;Auto.js自动化工具全揭秘 【免费下载链接】Auto.js微信跳一跳辅助说明分享 Auto.js微信跳一跳辅助说明 项目地址: https://gitcode.com/Open-source-documentation-tutorial/747cc 还在为微信跳一跳的难度而烦恼吗&#xff1f;想要轻松突…

作者头像 李华
网站建设 2026/8/22 15:05:10

tmom生产制造系统:制造业数字化转型的终极解决方案

您是否正在为生产数据不透明、工艺变更频繁、多厂区管理困难而烦恼&#xff1f;tmom生产制造系统正是为解决这些制造业痛点而生的强大工具。作为一款开源的多厂区MOM/MES系统&#xff0c;它集成了计划排程、工艺设计、在线低代码报表等核心功能&#xff0c;让您轻松实现数字化转…

作者头像 李华
网站建设 2026/8/19 15:47:26

AI图像标注神器:5分钟掌握智能打标技巧

AI图像标注神器&#xff1a;5分钟掌握智能打标技巧 【免费下载链接】GPT4V-Image-Captioner 项目地址: https://gitcode.com/gh_mirrors/gp/GPT4V-Image-Captioner 想要快速为大量图片添加精准描述&#xff1f;GPT4V-Image-Captioner 这款强大的AI图像打标工具就是你的…

作者头像 李华