使用Node-API接口设置ArkTS对象的属性
========================

#### 简介

使用Node-API接口获取和设置ArkTS对象的属性，实现更复杂的功能和逻辑。

#### 基本概念

处理ArkTS对象属性，确保正确访问、设置、删除属性，并了解属性的继承关系和枚举特性。以下是一些关键概念：

*   **对象（Object）**：在ArkTS中，对象是一种复合数据类型，它允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值，而方法则是对象可以执行的操作。
*   **属性（Property）**：在ArkTS中，属性是对象特征的键值对。每个属性都有一个名字（也称为键或标识符）和一个值。属性的值可以是任意数据类型，包括基本类型、对象和函数。
*   **可枚举属性（EnumerableProperty）**：在ArkTS中，对象的属性分为可枚举和不可枚举，它们是由属性的enumerable值决定的，即内部 “可枚举” 标志设置为true或false。可枚举性决定了这个属性能否被 for...in 查找遍历到。
*   **自有属性（OwnProperty）**：自有属性是直接定义在对象上的属性，而不是从原型链上继承来的属性。

#### 场景和功能介绍

以下Node-API接口提供了对ArkTS对象属性的操作，包括设置、获取、删除和检查属性是否存在。使用场景如下：

| 接口 | 描述 |
| :-- | :-- |
| napi\_get\_property\_names | 在进行对象操作或调试时，有时需要获取对象的属性和属性名。此接口可以提取对象的属性名，用于动态获取对象的属性信息。 |
| napi\_set\_property | 此接口可以动态地向对象添加属性。也可修改对象的属性值，满足动态属性值变更的需求。 |
| napi\_get\_property | 在调用Node-API模块的函数或方法时，可能需要将ArkTS对象的属性值作为参数传递。此接口可以获取属性值，并将其传递给其他函数。 |
| napi\_has\_property | 在进行属性访问之前，通常需要先检查对象中是否存在指定的属性。此接口可以检查对象中是否存在指定的属性，避免访问不存在属性导致的异常。 |
| napi\_delete\_property | 此函数用于删除ArkTS对象上的属性。 |
| napi\_has\_own\_property | 此函数用于检查ArkTS对象是否直接拥有（而不是从其原型链上继承）某个属性。 |
| napi\_set\_named\_property | 此函数用于将值赋给ArkTS对象的命名属性。 |
| napi\_get\_named\_property | 此函数用于获取ArkTS对象的命名属性值。 |
| napi\_has\_named\_property | 此函数用于检查ArkTS对象是否包含某个命名属性。 |
| napi\_define\_properties | 此函数可以在指定的Object中自定义属性，从ArkTS访问和操作这些属性。 |
| napi\_get\_all\_property\_names | 此接口可以获取对象的所有属性名称，检查是否包含特定属性名。 |

#### 使用示例

Node-API接口开发流程可参考[使用Node-API实现跨语言交互开发流程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-process)，本文展示接口对应C++及ArkTS代码。

#### \[h2\]napi\_get\_property\_names

以字符串数组的形式获取对象的可枚举属性的名称。

cpp部分代码

// napi\_get\_property\_names
static napi\_value GetPropertyNames(napi\_env env, napi\_callback\_info info)
{
    // 解析ArkTS的传参
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 以字符串数组的形式获取对象的可枚举属性的名称，以result传出
    napi\_value result;
    napi\_status status = napi\_get\_property\_names(env, args\[0\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_get\_property\_names fail");
        return nullptr;
    }
    return result;
}

接口声明

export const getPropertyNames: (obj: Object) => Array<string> | undefined; // napi\_get\_property\_names

ArkTS侧示例代码

// napi\_get\_property\_names
try {
  class Obj {
    public data: number = 0
    public message: string = ''
  }

  let obj: Obj = { data: 0, message: 'hello world' };
  let propertyNames = testNapi.getPropertyNames(obj);
  if (Array.isArray(propertyNames) && propertyNames.length > 0) {
    hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_property\_names: %{public}s',
      propertyNames\[0\]);
    hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_property\_names: %{public}s',
      propertyNames\[1\]);
    // ...
  }
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_get\_property\_names error: %{public}s',
    error.message);
  // ...
}

#### \[h2\]napi\_set\_property

将给定的属性与值设置入给定的Object。

cpp部分代码

// napi\_set\_property
static napi\_value SetProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收ArkTS侧传入的三个参数：第一个参数为想要设置的object，第二个参数为属性，第三个参数为属性对应的值
    size\_t argc = 3;
    napi\_value args\[3\] = {nullptr};
    napi\_status status = napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_get\_cb\_info fail");
    }
    // 通过调用napi\_set\_property接口将属性与值设置入object，如果失败，直接抛出错误
    status = napi\_set\_property(env, args\[0\], args\[1\], args\[INT\_ARG\_2\]);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_set\_property fail");
        return nullptr;
    }
    // 返回设置成功的object对象
    return args\[0\];
}

接口声明

export const setProperty: (obj: Object, key: String, value: string) => Object | undefined; // napi\_set\_property

ArkTS侧示例代码

// napi\_set\_property
try {
  class Obj {
    public data: number = 0
    public message: string = ''
  }

  let obj: Obj = { data: 0, message: 'hello world' };
  let result = testNapi.setProperty(obj, 'code', 'hi');
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_property: %{public}s',
    JSON.stringify(result));
  // ...
} catch (error) {
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_property error: %{public}s', error.message);
  // ...
}

#### \[h2\]napi\_get\_property

获取object指定的属性的值。

cpp部分代码

// napi\_get\_property
static napi\_value GetProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收两个ArkTS传来的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 传入的第一个参数为要检测的object，第二个对象为要检测的属性，通过调用napi\_get\_property接口获取对应的值
    napi\_value result;
    napi\_status status = napi\_get\_property(env, args\[0\], args\[1\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_get\_property fail");
        return nullptr;
    }
    return result;
}

接口声明

export const getProperty: (obj: Object, key: string) => string | undefined; // napi\_get\_property

ArkTS侧示例代码

// napi\_get\_property
try {
  class Obj {
    public data: number = 0
    public message: string = ''
  }

  let obj: Obj = { data: 0, message: 'hello world' };
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_property: %{public}s',
    testNapi.getProperty(obj, 'message'));
  // ...
} catch (error) {
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_property error: %{public}s', error.message);
  // ...
}

#### \[h2\]napi\_has\_property

检查对象中是否存在指定的属性，避免访问不存在属性导致的异常。

cpp部分代码

// napi\_has\_property
static napi\_value HasProperty(napi\_env env, napi\_callback\_info info)
{
    // 从ArkTS侧传入两个参数：第一个参数为要检验的对象，第二个参数为要检测是否存在对象的属性
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);

    // 将参数传入napi\_has\_property方法中，若接口调用成功则将结果转化为napi\_value类型抛出，否则抛出错误
    bool result;
    napi\_status status = napi\_has\_property(env, args\[0\], args\[1\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_has\_property fail");
        return nullptr;
    }

    // 若传入属性存在传入对象中，则输出true将结果转化为napi\_value类型抛出
    napi\_value returnResult;
    napi\_get\_boolean(env, result, &returnResult);
    return returnResult;
}

接口声明

export const hasProperty: (obj: Object, key: number | string) => boolean | undefined; // napi\_has\_property

ArkTS侧示例代码

// napi\_has\_property
try {
  class Obj {
    public data: number = 0
    public message: string = ''
  }

  let obj: Obj = { data: 0, message: 'hello world' };
  let resultFalse = testNapi.hasProperty(obj, 0);
  let resultTrue = testNapi.hasProperty(obj, 'data');
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_property: %{public}s',
    JSON.stringify(resultFalse));
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_property: %{public}s',
    JSON.stringify(resultTrue));
  // ...
} catch (error) {
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_property error: %{public}s', error.message);
  // ...
}

#### \[h2\]napi\_delete\_property

尝试从给定的Object中删除由key指定的属性，并返回操作的结果。

如果对象不可扩展或属性不可配置，则可能无法删除该属性。

cpp部分代码

// napi\_delete\_property
// 从传入的Object对象中删除指定属性，返回是否删除成功的bool结果值
static napi\_value DeleteProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收两个ArkTS传来的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);

    napi\_valuetype valueType;
    napi\_typeof(env, args\[0\], &valueType);
    if (valueType != napi\_object) {
        napi\_throw\_error(env, nullptr, "Expects an object as argument.");
        return nullptr;
    }
    // 删除指定属性，结果存储在result中
    bool result = false;
    napi\_status status = napi\_delete\_property(env, args\[0\], args\[1\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_delete\_property failed");
        return nullptr;
    }
    // 将bool结果转换为napi\_value并返回
    napi\_value ret;
    napi\_get\_boolean(env, result, &ret);
    return ret;
}

接口声明

export const deleteProperty: (obj: Object, key: string) => boolean; // napi\_delete\_property

ArkTS侧示例代码

import testNapi from 'libentry.so';
import { hilog } from '@kit.PerformanceAnalysisKit';

export function napiDeleteProperty() {
  class Obj {
    first: number = 0;
  }

  let obj: Obj = { first: 1 };
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_delete\_property first: %{public}s',
    testNapi.deleteProperty(obj, 'first'));
  // Set the new property as non-configurable
  // The Object.defineProperty method is not supported in DevEco Studio 4.1.0.400 and above versions, and needs to be used in TS (TypeScript)
  Object.defineProperty(obj, 'config', {
    configurable: false,
    value: 'value'
  })
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_delete\_property config: %{public}s',
    testNapi.deleteProperty(obj, 'config'));
}

#### \[h2\]napi\_has\_own\_property

用于检查传入的Object是否包含自己的命名属性，不包括从原型链上继承的属性。

cpp部分代码

// napi\_has\_own\_property
static napi\_value NapiHasOwnProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收两个ArkTS传来的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 检查第一个参数是否为对象
    napi\_valuetype valueTypeObj;
    napi\_typeof(env, args\[0\], &valueTypeObj);
    if (valueTypeObj != napi\_object) {
        napi\_throw\_error(env, nullptr, "First argument must be an object.");
        return nullptr;
    }
    // 检查第二个参数是否为string
    napi\_valuetype valuetypeStr;
    napi\_typeof(env, args\[1\], &valuetypeStr);
    if (valuetypeStr != napi\_string) {
        napi\_throw\_error(env, nullptr, "Second argument must be a string.");
        return nullptr;
    }
    // 检查对象是否具有指定属性，结果存储在hasProperty中
    bool hasProperty;
    napi\_status status = napi\_has\_own\_property(env, args\[0\], args\[1\], &hasProperty);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_has\_own\_property failed");
        return nullptr;
    }
    // 将bool结果转换为napi\_value并返回
    napi\_value result;
    napi\_get\_boolean(env, hasProperty, &result);
    return result;
}

接口声明

export const napiHasOwnProperty: (obj: Object, key: string) => boolean | undefined; // napi\_has\_own\_property

ArkTS侧示例代码

import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

export function napiHasOwnProperty() {
  let myObj = { 'myProperty': 1 };
  let inheritedObj = { 'inheritedProperty': 2 };
  // The Object.setPrototypeOf method is not supported in DevEco Studio 4.1.0.400 and later versions, and must be used in TypeScript (TS).
  Object.setPrototypeOf(myObj, inheritedObj);
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_own\_property my: %{public}s',
    testNapi.napiHasOwnProperty(myObj, 'myProperty'));
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_own\_property inherited: %{public}s',
    testNapi.napiHasOwnProperty(myObj, 'inheritedProperty'));
}

#### \[h2\]napi\_set\_named\_property

在传入的ArkTS对象上添加一个命名属性。

cpp部分代码

// napi\_set\_named\_property
static napi\_value NapiSetNamedProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收一个ArkTS传来的参数
    size\_t argc = 1;
    napi\_value str;
    const int32\_t strLength = 32;
    char strKey\[strLength\] = "";
    napi\_get\_cb\_info(env, info, &argc, &str, nullptr, nullptr);
    // 获取传入参数字符串并存储在strKey中
    size\_t keyLength;
    napi\_status status = napi\_get\_value\_string\_utf8(env, str, strKey, strLength, &keyLength);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_get\_value\_string\_utf8 failed");
        return nullptr;
    }
    // 创建一个新对象
    napi\_value newObj;
    napi\_create\_object(env, &newObj);
    // 设置整数值1234为属性值
    int32\_t value = 1234;
    napi\_value numValue;
    napi\_create\_int32(env, value, &numValue);
    // 将整数值与指定属性名关联
    status = napi\_set\_named\_property(env, newObj, strKey, numValue);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_set\_named\_property failed");
        return nullptr;
    }
    // 返回设置了命名属性的对象newObj
    return newObj;
}

接口声明

export const napiSetNamedProperty: (key: string) => Object | undefined; // napi\_set\_named\_property

ArkTS侧示例代码

// napi\_set\_named\_property
let obj = testNapi.napiSetNamedProperty('myProperty');
let objAsString = JSON.stringify(obj);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_named\_property: %{public}s', objAsString);

#### \[h2\]napi\_get\_named\_property

从ArkTS对象中获取命名属性的值。

cpp部分代码

// napi\_get\_named\_property
static napi\_value NapiGetNamedProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收两个ArkTS传来的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    const int32\_t strLength = 32;
    char strKey\[strLength\] = "";
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 获取要获取的属性名
    size\_t keyLength;
    napi\_get\_value\_string\_utf8(env, args\[1\], strKey, strLength, &keyLength);
    // 获取指定属性的值并存储在result中
    napi\_value result;
    napi\_status status = napi\_get\_named\_property(env, args\[0\], strKey, &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_get\_named\_property failed");
        return nullptr;
    }
    // 返回result
    return result;
}

接口声明

export const napiGetNamedProperty: (obj: Object,
  key: string) => boolean | number | string | Object | undefined; // napi\_get\_named\_property

ArkTS侧示例代码

// napi\_get\_named\_property
interface NestedObj {
  nestedStr: string;
  nestedNum: number;
}

class Obj {
  public str: string = '';
  public num: number = 0;
  public bol: boolean = false;
  public nestedObj: NestedObj = { nestedStr: '', nestedNum: 0 };
}

let obj: Obj = {
  str: 'bar',
  num: 42,
  bol: true,
  nestedObj: { nestedStr: 'nestedValue', nestedNum: 123 }
};
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_named\_property : %{public}s',
  testNapi.napiGetNamedProperty(obj, 'str'));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_named\_property : %{public}d',
  testNapi.napiGetNamedProperty(obj, 'num'));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_named\_property : %{public}s',
  testNapi.napiGetNamedProperty(obj, 'bol'));
let nestedObj = testNapi.napiGetNamedProperty(obj, 'nestedObj');
let objAsString = JSON.stringify(nestedObj);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_named\_property : %{public}s', objAsString);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_named\_property : %{public}s',
  testNapi.napiGetNamedProperty(obj, 'null'));

#### \[h2\]napi\_has\_named\_property

检查ArkTS对象中是否具有指定的命名属性。

cpp部分代码

// napi\_has\_named\_property
static napi\_value NapiHasNamedProperty(napi\_env env, napi\_callback\_info info)
{
    // 接收两个ArkTS传来的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    const int32\_t strLength = 32;
    char strKey\[strLength\] = "";
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 获取要检查的属性名
    size\_t keyLength;
    napi\_get\_value\_string\_utf8(env, args\[1\], strKey, strLength, &keyLength);
    // 检查对象是否具有指定命名的属性，并将结果存储在hasProperty中
    bool hasProperty = false;
    napi\_status status = napi\_has\_named\_property(env, args\[0\], strKey, &hasProperty);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_has\_named\_property failed");
        return nullptr;
    }
    // 将bool结果转换为napi\_value并返回
    napi\_value result;
    napi\_get\_boolean(env, hasProperty, &result);
    return result;
}

接口声明

export const napiHasNamedProperty: (obj: Object, key: string) => boolean | undefined; // napi\_has\_named\_property

ArkTS侧示例代码

// napi\_has\_named\_property
interface NestedObj {
  nestedStr: string;
  nestedNum: number;
}

class Obj {
  public str: string = '';
  public num: number = 0;
  public bol: boolean = false;
  public nestedObj: NestedObj = { nestedStr: '', nestedNum: 0 };
}

let obj: Obj = {
  str: 'bar',
  num: 42,
  bol: true,
  nestedObj: { nestedStr: 'nestedValue', nestedNum: 123 }
};
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_named\_property : %{public}s',
  testNapi.napiHasNamedProperty(obj, 'str'));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_named\_property : %{public}s',
  testNapi.napiHasNamedProperty(obj, 'nestedStr'));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_named\_property : %{public}s',
  testNapi.napiHasNamedProperty(obj, 'bol'));

#### \[h2\]napi\_define\_properties

设置对象的属性。

cpp部分代码

// napi\_define\_properties
static napi\_value DefineMethodPropertiesExample(napi\_env env, napi\_callback\_info info)
{
    // 创建一个int32类型的属性值
    int32\_t propValue = 26;
    napi\_value returnValue = nullptr;
    napi\_create\_int32(env, propValue, &returnValue);
    return returnValue;
}

// Getter回调函数
static napi\_value GetterCallback(napi\_env env, napi\_callback\_info info)
{
    napi\_value result;
    const char \*str = u8"World!";
    size\_t length = strlen(str);
    // 创建属性的值
    napi\_create\_string\_utf8(env, str, length, &result);
    return result;
}

// Setter回调函数
static napi\_value SetterCallback(napi\_env env, napi\_callback\_info info)
{
    // 获取传递给setter的参数
    size\_t argc = 1;
    napi\_value argv\[1\] = {nullptr};
    napi\_value result;
    napi\_get\_cb\_info(env, info, &argc, argv, nullptr, nullptr);
    size\_t length = 0;
    napi\_get\_value\_string\_utf8(env, argv\[0\], nullptr, 0, &length);
    char\* buf = new char\[length + 1\];
    std::memset(buf, 0, length + 1);
    napi\_get\_value\_string\_utf8(env, argv\[0\], buf, length + 1, &length);
    napi\_create\_string\_utf8(env, buf, length, &result);
    delete\[\] buf;
    return result;
}

static napi\_value DefineMethodProperties(napi\_env env, napi\_callback\_info info)
{
    napi\_value obj;
    napi\_create\_object(env, &obj);
    // 在obj对象上定义了一个函数defineMethodPropertiesExample，在函数defineMethodPropertiesExample中定义了一个变量并返回，在调用obj的这个对象时可以调用这个函数
    napi\_property\_descriptor descriptor\[\] = {{"defineMethodPropertiesExample", nullptr, DefineMethodPropertiesExample,
                                              nullptr, nullptr, nullptr, napi\_default, nullptr}};
    napi\_define\_properties(env, obj, sizeof(descriptor) / sizeof(descriptor\[0\]), descriptor);
    return obj;
}

static napi\_value DefineStringProperties(napi\_env env, napi\_callback\_info info)
{
    napi\_value obj;
    napi\_create\_object(env, &obj);
    // 创建一个string类型的属性值
    napi\_value string\_value;
    napi\_create\_string\_utf8(env, "Hello!", NAPI\_AUTO\_LENGTH, &string\_value);
    napi\_property\_descriptor descriptor\[\] = {
        {"defineStringPropertiesExample", nullptr, nullptr, nullptr, nullptr, string\_value, napi\_default, nullptr}};
    napi\_define\_properties(env, obj, sizeof(descriptor) / sizeof(descriptor\[0\]), descriptor);
    return obj;
}

static napi\_value CreateStringWithGetterSetter(napi\_env env, napi\_callback\_info info)
{
    napi\_value obj;
    napi\_create\_object(env, &obj);
    // 定义getter函数
    napi\_value getterFn;
    napi\_create\_function(env, nullptr, 0, GetterCallback, nullptr, &getterFn);
    napi\_set\_named\_property(env, obj, "getterCallback", getterFn);
    // 定义setter函数
    napi\_value setterFn;
    napi\_create\_function(env, nullptr, 0, SetterCallback, nullptr, &setterFn);
    napi\_set\_named\_property(env, obj, "setterCallback", setterFn);
    // 定义带有getter和setter的属性
    napi\_property\_descriptor desc = {"defineGetterSetter", nullptr, nullptr, GetterCallback, SetterCallback, nullptr,
                                     napi\_enumerable, nullptr};
    napi\_define\_properties(env, obj, 1, &desc);
    return obj;
}

接口声明

export class DefineMethodObj {
  defineMethodPropertiesExample: Function;
}

export class DefineStringObj {
  defineStringPropertiesExample: string;
}

export class DefineGetterSetterObj {
  getterCallback: Function;
  setterCallback: Function;
}

export const defineMethodProperties: () => DefineMethodObj; // napi\_define\_properties

export const defineStringProperties: () => DefineStringObj;

export const createStringWithGetterSetter: () => DefineGetterSetterObj;

ArkTS侧示例代码

// napi\_define\_properties
// 定义method类型的属性
hilog.info(0x0000, 'testTag', 'Test Node-API define\_method\_properties:%{public}d',
  testNapi.defineMethodProperties()
    .defineMethodPropertiesExample());
// 定义string类型的属性
hilog.info(0x0000, 'testTag', 'Test Node-API define\_string\_properties::%{public}s ',
  testNapi.defineStringProperties()
    .defineStringPropertiesExample);
// getter和setter
hilog.info(0x0000, 'testTag', 'Test Node-API get::%{public}s ',
  testNapi.createStringWithGetterSetter()
    .getterCallback());
hilog.info(0x0000, 'testTag', 'Test Node-API setter::%{public}s ',
  testNapi.createStringWithGetterSetter()
    .setterCallback('set data'));

#### \[h2\]napi\_get\_all\_property\_names

获取传入的ArkTS对象的所有属性名。

cpp部分代码

// napi\_get\_all\_property\_names
static napi\_value GetAllPropertyNames(napi\_env env, napi\_callback\_info info)
{
    // 传入一个参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);

    // 获取给定对象的所有属性名称
    napi\_value result;
    napi\_status status = napi\_get\_all\_property\_names(env, args\[0\], napi\_key\_own\_only, napi\_key\_writable,
                                                     napi\_key\_numbers\_to\_strings, &result);
    // 如果获取属性名失败，抛出一个错误
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_get\_all\_property\_names fail");
        return nullptr;
    }

    return result;
}

接口声明

export const getAllPropertyNames: (obj: Object) => Array<string> | undefined; // napi\_get\_all\_property\_names

ArkTS侧示例代码

// napi\_get\_all\_property\_names
try {
  class Obj {
    public data: number = 0
    public message: string = ''
  }

  let obj: Obj = { data: 0, message: 'hello world' };
  let propertyNames = testNapi.getAllPropertyNames(obj);
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_all\_property\_names: %{public}s',
    JSON.stringify(propertyNames));
  // ...
} catch (error) {
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_all\_property\_names error: %{public}s',
    error.message);
  // ...
}

以上代码如果要在native cpp中打印日志，需在CMakeLists.txt文件中添加以下配置信息（并添加头文件：#include "hilog/log.h"）：

// CMakeLists.txt
add\_definitions( "-DLOG\_DOMAIN=0xd0d0" )
add\_definitions( "-DLOG\_TAG=\\"testTag\\"" )
target\_link\_libraries(entry PUBLIC libace\_napi.z.so libhilog\_ndk.z.so)