• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用Node-API接口设置ArkTS对象的属性
2
3## 简介
4
5使用Node-API接口获取和设置ArkTS对象的属性。通过合理使用这些函数,实现更复杂的功能和逻辑。
6
7## 基本概念
8
9在ArkTS对象属性的相关开发中,需要处理ArkTS对象属性,确保正确地访问、设置、删除属性,并了解属性的继承关系和枚举特性。以下是一些关键概念:
10
11- **对象(Object)**:在ArkTS中,对象是一种复合数据类型,它允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值,而方法则是对象可以执行的操作。
12- **属性(Property)**:在ArkTS中,属性是对象特征的键值对。每个属性都有一个名字(也称为键或标识符)和一个值。属性的值可以是任意数据类型,包括基本类型、对象和函数。
13- **可枚举属性(EnumerableProperty)**:在ArkTS中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的,即内部 “可枚举” 标志设置为true或false。可枚举性决定了这个属性能否被 `for...in` 查找遍历到。
14- **自有属性(OwnProperty)**:自有属性直接定义在对象上的属性,而不是从原型链上继承来的属性。
15
16## 场景和功能介绍
17
18以下Node-API接口提供了对ArkTS对象属性的基本操作,包括设置、获取、删除和检查属性是否存在。使用场景如下:
19| 接口 | 描述 |
20| -------- | -------- |
21| napi_get_property_names | 在进行对象操作或调试时,有时需要获取对象的属性和属性名。此接口可以帮助提取对象的属性名,用于动态获取对象的属性信息的场景。 |
22| napi_set_property | 通过此接口可以动态地向对象添加属性。也可修改对象的属性值,满足动态属性值变更的需求。 |
23| napi_get_property | 在调用Node-API模块的函数或方法时,可能需要将ArkTS对象的属性值作为参数传递。通过此接口可以获取属性值,并将其传递给其他函数进行处理。 |
24| napi_has_property | 在进行属性访问之前,通常需要先检查对象中是否存在指定的属性。通过调用此接口可以判断给定对象是否包含特定的属性,从而避免访问不存在属性导致的异常或错误。 |
25| napi_delete_property | 在需要删除一个ArkTS对象上的某个属性时,可以使用这个函数。 |
26| napi_has_own_property | 在需要检查一个ArkTS对象是否直接拥有(而不是从其原型链上继承)某个属性时,可以使用这个函数。 |
27| napi_set_named_property | 在需要将一个值赋给ArkTS对象的命名属性时,可以使用这个函数。 |
28| napi_get_named_property | 在需要从ArkTS对象中获取一个命名属性的值时,可以使用这个函数。 |
29| napi_has_named_property | 在需要检查一个ArkTS对象是否包含某个命名属性时,可以使用这个函数。 |
30| napi_define_properties | 当需要在指定Object中自定义属性,并从ArkTS中访问和操作这些属性时,可以使用这个函数。 |
31| napi_get_all_property_names | 当需要遍历一个对象的所有属性,并对其进行处理时,可以使用此接口获取所有属性名称的数组,然后检查数组中是否包含特定的属性名。 |
32
33## 使用示例
34
35Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
36
37### napi_get_property_names
38
39以字符串数组的形式获取对象的可枚举属性的名称。
40
41cpp部分代码
42
43```cpp
44#include "napi/native_api.h"
45
46static napi_value GetPropertyNames(napi_env env, napi_callback_info info)
47{
48    // 解析ArkTS的传参
49    size_t argc = 1;
50    napi_value args[1] = {nullptr};
51    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
52    // 以字符串数组的形式获取对象的可枚举属性的名称,以result传出
53    napi_value result;
54    napi_status status = napi_get_property_names(env, args[0], &result);
55    if (status != napi_ok) {
56        napi_throw_error(env, nullptr, "Node-API napi_get_property_names fail");
57        return nullptr;
58    }
59    return result;
60}
61```
62
63接口声明
64
65```ts
66// index.d.ts
67export const getPropertyNames: (obj: Object) => Array<string> | void;
68```
69
70ArkTS侧示例代码
71
72```ts
73import hilog from '@ohos.hilog'
74import testNapi from 'libentry.so'
75try {
76  class Obj {
77    data: number = 0
78    message: string = ""
79  }
80  let obj: Obj = { data: 0, message: "hello world"};
81  let propertyNames = testNapi.getPropertyNames(obj);
82  if (Array.isArray(propertyNames) && propertyNames.length > 0) {
83    hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_property_names: %{public}s', propertyNames[0]);
84    hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_property_names: %{public}s', propertyNames[1]);
85  }
86} catch (error) {
87  hilog.error(0x0000, 'testTag', 'Test Node-API napi_get_property_names error: %{public}s', error.message);
88}
89```
90
91### napi_set_property
92
93将给定的属性与值设置入给定的Object。
94
95cpp部分代码
96
97```cpp
98#include "napi/native_api.h"
99
100static constexpr int INT_ARG_2 = 2; // 入参索引
101
102static napi_value SetProperty(napi_env env, napi_callback_info info)
103{
104    // 接收ArkTS侧传入的三个参数:第一个参数为想要设置的object,第二个参数为属性,第三个参数为属性对应的值
105    size_t argc = 3;
106    napi_value args[3] = {nullptr};
107    napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
108    if (status != napi_ok) {
109        napi_throw_error(env, nullptr, "Node-API napi_get_cb_info fail");
110    }
111    // 通过调用napi_set_property接口将属性与值设置入object,如果失败,直接抛出错误
112    status = napi_set_property(env, args[0], args[1], args[INT_ARG_2]);
113    if (status != napi_ok) {
114        napi_throw_error(env, nullptr, "Node-API napi_set_property fail");
115        return nullptr;
116    }
117    // 返回设置成功的object对象
118    return args[0];
119}
120```
121
122接口声明
123
124```ts
125// index.d.ts
126export const setProperty: (obj: Object, key: String, value: string) => Object | void;
127```
128
129ArkTS侧示例代码
130
131```ts
132import hilog from '@ohos.hilog'
133import testNapi from 'libentry.so'
134try {
135  class Obj {
136    data: number = 0
137    message: string = ""
138  }
139  let obj: Obj = { data: 0, message: "hello world"};
140  let result = testNapi.setProperty(obj, "code", "hi");
141  hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_property: %{public}s', JSON.stringify(result));
142} catch (error) {
143  hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_property error: %{public}s', error.message);
144}
145```
146
147### napi_get_property
148
149获取object指定的属性的值。
150
151cpp部分代码
152
153```cpp
154#include "napi/native_api.h"
155
156static napi_value GetProperty(napi_env env, napi_callback_info info)
157{
158    // 接收两个ArkTS传来的参数
159    size_t argc = 2;
160    napi_value args[2] = {nullptr};
161    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
162    // 传入的第一个参数为要检测的object,第二个对象为要检测的属性,通过调用napi_get_property接口获取对应的值
163    napi_value result;
164    napi_status status = napi_get_property(env, args[0], args[1], &result);
165    if (status != napi_ok) {
166        napi_throw_error(env, nullptr, "Node-API napi_get_property fail");
167        return nullptr;
168    }
169    return result;
170}
171```
172
173接口声明
174
175```ts
176// index.d.ts
177export const getProperty: (obj: Object, key: string) => string | void;
178```
179
180ArkTS侧示例代码
181
182```ts
183import hilog from '@ohos.hilog'
184import testNapi from 'libentry.so'
185try {
186  class Obj {
187    data: number = 0
188    message: string = ""
189  }
190  let obj: Obj = { data: 0, message: "hello world"};
191  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_property: %{public}s', testNapi.getProperty(obj, "message"));
192} catch (error) {
193  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_property error: %{public}s', error.message);
194}
195```
196
197### napi_has_property
198
199检查对象中是否存在指定的属性,可以避免访问不存在属性导致的异常或错误。
200
201cpp部分代码
202
203```cpp
204#include "napi/native_api.h"
205
206static napi_value HasProperty(napi_env env, napi_callback_info info)
207{
208    // 从ArkTS侧传入两个参数:第一个参数为要检验的对象,第二个参数为要检测是否存在对象的属性
209    size_t argc = 2;
210    napi_value args[2] = {nullptr};
211    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
212
213    // 将参数传入napi_has_property方法中,若接口调用成功则将结果转化为napi_value类型抛出,否则抛出错误
214    bool result;
215    napi_status status = napi_has_property(env, args[0], args[1], &result);
216    if (status != napi_ok) {
217        napi_throw_error(env, nullptr, "Node-API napi_has_property fail");
218        return nullptr;
219    }
220
221    // 若传入属性存在传入对象中,则输出true将结果转化为napi_value类型抛出
222    napi_value returnResult;
223    napi_get_boolean(env, result, &returnResult);
224    return returnResult;
225}
226```
227
228接口声明
229
230```ts
231// index.d.ts
232export const hasProperty: (obj: Object, key: number | string) => boolean | void;
233```
234
235ArkTS侧示例代码
236
237```ts
238import hilog from '@ohos.hilog'
239import testNapi from 'libentry.so'
240try {
241  class Obj {
242    data: number = 0
243    message: string = ""
244  }
245  let obj: Obj = { data: 0, message: "hello world"};
246  let resultFalse = testNapi.hasProperty(obj, 0);
247  let resultTrue = testNapi.hasProperty(obj, "data");
248  hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_property: %{public}s', JSON.stringify(resultFalse));
249  hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_property: %{public}s', JSON.stringify(resultTrue));
250} catch (error) {
251  hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_property error: %{public}s', error.message);
252}
253```
254
255### napi_delete_property
256
257尝试从给定的Object中删除由key指定的属性,并返回操作的结果。
258如果对象是一个不可扩展的对象,或者属性是不可配置的,则可能无法删除该属性。
259
260cpp部分代码
261
262```cpp
263#include "napi/native_api.h"
264
265// 从传入的Object对象中删除指定属性,返回是否删除成功的bool结果值
266static napi_value DeleteProperty(napi_env env, napi_callback_info info)
267{
268    // 接收两个ArkTS传来的参数
269    size_t argc = 2;
270    napi_value args[2] = {nullptr};
271    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
272
273    napi_valuetype valueType;
274    napi_typeof(env, args[0], &valueType);
275    if (valueType != napi_object) {
276        napi_throw_error(env, nullptr, "Expects an object as argument.");
277        return nullptr;
278    }
279    // 删除指定属性,结果存储在result中
280    bool result = false;
281    napi_status status = napi_delete_property(env, args[0], args[1], &result);
282    if (status != napi_ok) {
283        napi_throw_error(env, nullptr, "Node-API napi_delete_property failed");
284        return nullptr;
285    }
286    // 将bool结果转换为napi_value并返回
287    napi_value ret;
288    napi_get_boolean(env, result, &ret);
289    return ret;
290}
291```
292
293接口声明
294
295```ts
296// index.d.ts
297export const deleteProperty: (obj: Object, key:string) => boolean;
298```
299
300ArkTS侧示例代码
301
302```ts
303import hilog from '@ohos.hilog'
304import testNapi from 'libentry.so'
305class Obj {
306  first: number = 0;
307}
308let obj: Obj = { first: 1};
309hilog.info(0x0000, 'testTag', 'Test Node-API napi_delete_property first: %{public}s', testNapi.deleteProperty(obj, 'first'));
310// 设置新的属性为不可配置
311// 这里的Object.defineProperty方法在DevEco Studio 4.1.0.400及其以上版本不支持,需在ts使用
312Object.defineProperty(obj, 'config', {
313  configurable: false,
314  value: "value"
315})
316hilog.info(0x0000, 'testTag', 'Test Node-API napi_delete_property config: %{public}s', testNapi.deleteProperty(obj, 'config'));
317```
318
319### napi_has_own_property
320
321用于检查传入的Object是否具有自己的命名属性,不包括从原型链上继承的属性。
322
323cpp部分代码
324
325```cpp
326#include "napi/native_api.h"
327
328static napi_value NapiHasOwnProperty(napi_env env, napi_callback_info info)
329{
330    // 接收两个ArkTS传来的参数
331    size_t argc = 2;
332    napi_value args[2] = {nullptr};
333    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
334    // 检查第一个参数是否为对象
335    napi_valuetype valueTypeObj;
336    napi_typeof(env, args[0], &valueTypeObj);
337    if (valueTypeObj != napi_object) {
338        napi_throw_error(env, nullptr, "First argument must be an object.");
339        return nullptr;
340    }
341    // 检查第二个参数是否为string
342    napi_valuetype valuetypeStr;
343    napi_typeof(env, args[1], &valuetypeStr);
344    if (valuetypeStr != napi_string) {
345        napi_throw_error(env, nullptr, "Second argument must be a string.");
346        return nullptr;
347    }
348    // 检查对象是否具有指定属性,结果存储在hasProperty中
349    bool hasProperty;
350    napi_status status = napi_has_own_property(env, args[0], args[1], &hasProperty);
351    if (status != napi_ok) {
352        napi_throw_error(env, nullptr, "napi_has_own_property failed");
353        return nullptr;
354    }
355    // 将bool结果转换为napi_value并返回
356    napi_value result;
357    napi_get_boolean(env, hasProperty, &result);
358    return result;
359}
360```
361
362接口声明
363
364```ts
365// index.d.ts
366export const napiHasOwnProperty: (obj: Object, key:string) => boolean | void;
367```
368
369ArkTS侧示例代码
370
371```ts
372import hilog from '@ohos.hilog'
373import testNapi from 'libentry.so'
374
375let myObj = { 'myProperty': 1 };
376let inheritedObj = { 'inheritedProperty': 2 };
377// 这里的Object.setPrototypeOf方法在DevEco Studio 4.1.0.400及其以上版本不支持,需在ts使用
378Object.setPrototypeOf(myObj, inheritedObj);
379hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_own_property my: %{public}s', testNapi.napiHasOwnProperty(myObj, 'myProperty'));
380hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_own_property inherited: %{public}s', testNapi.napiHasOwnProperty(myObj, 'inheritedProperty'));
381```
382
383### napi_set_named_property
384
385用于在传入的ArkTS对象上设置一个命名属性。
386
387cpp部分代码
388
389```cpp
390#include "napi/native_api.h"
391
392static napi_value NapiSetNamedProperty(napi_env env, napi_callback_info info)
393{
394    // 接收一个ArkTS传来的参数
395    size_t argc = 1;
396    napi_value str;
397    const int32_t strLength = 32;
398    char strKey[strLength] = "";
399    napi_get_cb_info(env, info, &argc, &str, nullptr, nullptr);
400    // 获取传入参数字符串并存储在strKey中
401    size_t keyLength;
402    napi_get_value_string_utf8(env, str, strKey, strLength, &keyLength);
403    // 创建一个新对象
404    napi_value newObj;
405    napi_create_object(env, &newObj);
406    // 设置整数值1234为属性值
407    int32_t value = 1234;
408    napi_value numValue;
409    napi_create_int32(env, value, &numValue);
410    // 将整数值与指定属性名关联
411    napi_status status = napi_set_named_property(env, newObj, strKey, numValue);
412    if (status != napi_ok) {
413        napi_throw_error(env, nullptr, "napi_set_named_property failed");
414        return nullptr;
415    }
416    // 返回设置了命名属性的对象newObj
417    return newObj;
418}
419```
420
421接口声明
422
423```ts
424// index.d.ts
425export const napiSetNamedProperty: (key: string) => Object | void;
426```
427
428ArkTS侧示例代码
429
430```ts
431import hilog from '@ohos.hilog'
432import testNapi from 'libentry.so'
433
434let obj = testNapi.napiSetNamedProperty('myProperty');
435let objAsString = JSON.stringify(obj);
436hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_named_property: %{public}s', objAsString);
437```
438
439### napi_get_named_property
440
441用于从ArkTS对象中获取命名属性的值。
442
443cpp部分代码
444
445```cpp
446#include "napi/native_api.h"
447
448static napi_value NapiGetNamedProperty(napi_env env, napi_callback_info info)
449{
450    // 接收两个ArkTS传来的参数
451    size_t argc = 2;
452    napi_value args[2] = {nullptr};
453    const int32_t strLength = 32;
454    char strKey[strLength] = "";
455    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
456    // 获取要获取的属性名
457    size_t keyLength;
458    napi_get_value_string_utf8(env, args[1], strKey, strLength, &keyLength);
459    // 获取指定属性的值并存储在result中
460    napi_value result;
461    napi_status status = napi_get_named_property(env, args[0], strKey, &result);
462    if (status != napi_ok) {
463        napi_throw_error(env, nullptr, "napi_get_named_property failed");
464        return nullptr;
465    }
466    // 返回result
467    return result;
468}
469```
470
471接口声明
472
473```ts
474// index.d.ts
475export const napiGetNamedProperty: (obj: Object, key:string) => boolean | number | string | Object | void;
476```
477
478ArkTS侧示例代码
479
480```ts
481import hilog from '@ohos.hilog'
482import testNapi from 'libentry.so'
483
484interface NestedObj {
485  nestedStr: string;
486  nestedNum: number;
487}
488class Obj {
489  str: string = "";
490  num: number = 0;
491  bol: boolean = false;
492  nestedObj: NestedObj = { nestedStr: "", nestedNum: 0 };
493}
494let obj: Obj = {str: "bar", num: 42, bol: true,
495  nestedObj: { nestedStr: "nestedValue", nestedNum: 123 }};
496hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_named_property : %{public}s', testNapi.napiGetNamedProperty(obj, 'str'));
497hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_named_property : %{public}d', testNapi.napiGetNamedProperty(obj, 'num'));
498hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_named_property : %{public}s', testNapi.napiGetNamedProperty(obj, 'bol'));
499let nestedObj = testNapi.napiGetNamedProperty(obj, 'nestedObj');
500let objAsString = JSON.stringify(nestedObj);
501hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_named_property : %{public}s', objAsString);
502hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_named_property : %{public}s', testNapi.napiGetNamedProperty(obj, 'null'));
503```
504
505### napi_has_named_property
506
507用于检查ArkTS对象中是否包含指定的命名属性。
508
509cpp部分代码
510
511```cpp
512#include "napi/native_api.h"
513
514static napi_value NapiHasNamedProperty(napi_env env, napi_callback_info info)
515{
516    // 接收两个ArkTS传来的参数
517    size_t argc = 2;
518    napi_value args[2] = {nullptr};
519    const int32_t strLength = 32;
520    char strKey[strLength] = "";
521    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
522    // 获取要检查的属性名
523    size_t keyLength;
524    napi_get_value_string_utf8(env, args[1], strKey, strLength, &keyLength);
525    // 检查对象是否具有指定命名的属性,并将结果存储在hasProperty中
526    bool hasProperty = false;
527    napi_status status = napi_has_named_property(env, args[0], strKey, &hasProperty);
528    if (status != napi_ok) {
529        napi_throw_error(env, nullptr, "napi_has_named_property failed");
530        return nullptr;
531    }
532    // 将bool结果转换为napi_value并返回
533    napi_value result;
534    napi_get_boolean(env, hasProperty, &result);
535    return result;
536}
537```
538
539接口声明
540
541```ts
542// index.d.ts
543export const napiHasNamedProperty: (obj: Object, key:string) => boolean | void;
544```
545
546ArkTS侧示例代码
547
548```ts
549import hilog from '@ohos.hilog'
550import testNapi from 'libentry.so'
551interface NestedObj {
552  nestedStr: string;
553  nestedNum: number;
554}
555class Obj {
556  str: string = "";
557  num: number = 0;
558  bol: boolean = false;
559  nestedObj: NestedObj = { nestedStr: "", nestedNum: 0 };
560}
561let obj: Obj = {str: "bar", num: 42, bol: true,
562  nestedObj: { nestedStr: "nestedValue", nestedNum: 123 }};
563hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_named_property : %{public}s', testNapi.napiHasNamedProperty(obj, 'str'));
564hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_named_property : %{public}s', testNapi.napiHasNamedProperty(obj, 'nestedStr'));
565hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_named_property : %{public}s', testNapi.napiHasNamedProperty(obj, 'bol'));
566```
567
568### napi_define_properties
569
570用于定义对象的属性。
571
572cpp部分代码
573
574```cpp
575#include <string>
576#include "napi/native_api.h"
577
578static napi_value DefineMethodPropertiesExample(napi_env env, napi_callback_info info)
579{
580    // 创建一个int32类型的属性值
581    int32_t propValue = 26;
582    napi_value returnValue = nullptr;
583    napi_create_int32(env, propValue, &returnValue);
584    return returnValue;
585}
586// Getter回调函数
587static napi_value GetterCallback(napi_env env, napi_callback_info info)
588{
589    napi_value result;
590    const char *str = u8"World!";
591    size_t length = strlen(str);
592    // 创建属性的值
593    napi_create_string_utf8(env, str, length, &result);
594    return result;
595}
596
597// Setter回调函数
598static napi_value SetterCallback(napi_env env, napi_callback_info info)
599{
600    // 获取传递给setter的参数
601    size_t argc = 1;
602    napi_value argv[1] = {nullptr};
603    napi_value result;
604    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
605    size_t length = 0;
606    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &length);
607    char* buf = new char[length + 1];
608    std::memset(buf, 0, length + 1);
609    napi_get_value_string_utf8(env, argv[0], buf, length + 1, &length);
610    napi_create_string_utf8(env, buf, length, &result);
611    delete buf;
612    return result;
613}
614static napi_value DefineMethodProperties(napi_env env, napi_callback_info info)
615{
616    napi_value obj;
617    napi_create_object(env, &obj);
618    // 在obj对象上定义了一个函数defineMethodPropertiesExample,在函数defineMethodPropertiesExample中定义了一个变量并返回,在调用obj的这个对象时可以调用这个函数
619    napi_property_descriptor descriptor[] = {
620        {"defineMethodPropertiesExample", nullptr, DefineMethodPropertiesExample, nullptr, nullptr, nullptr, napi_default, nullptr}};
621    napi_define_properties(env, obj, sizeof(descriptor) / sizeof(descriptor[0]), descriptor);
622    return obj;
623}
624static napi_value DefineStringProperties(napi_env env, napi_callback_info info)
625{
626    napi_value obj;
627    napi_create_object(env, &obj);
628    // 创建一个string类型的属性值
629    napi_value string_value;
630    napi_create_string_utf8(env, "Hello!", NAPI_AUTO_LENGTH, &string_value);
631    napi_property_descriptor descriptor[] = {
632        {"defineStringPropertiesExample", nullptr, nullptr, nullptr, nullptr, string_value, napi_default, nullptr}};
633    napi_define_properties(env, obj, sizeof(descriptor) / sizeof(descriptor[0]), descriptor);
634    return obj;
635}
636
637static napi_value CreateStringWithGetterSetter(napi_env env, napi_callback_info info)
638{
639    napi_value obj;
640    napi_create_object(env, &obj);
641    // 定义getter函数
642    napi_value getterFn;
643    napi_create_function(env, nullptr, 0, GetterCallback, nullptr, &getterFn);
644    napi_set_named_property(env, obj, "getterCallback", getterFn);
645    // 定义setter函数
646    napi_value setterFn;
647    napi_create_function(env, nullptr, 0, SetterCallback, nullptr, &setterFn);
648    napi_set_named_property(env, obj, "setterCallback", setterFn);
649    // 定义带有getter和setter的属性
650    napi_property_descriptor desc = {"defineGetterSetter", nullptr, GetterCallback, SetterCallback, nullptr, obj, napi_enumerable, nullptr};
651    napi_define_properties(env, obj, 1, &desc);
652    return obj;
653}
654```
655
656接口声明
657
658```ts
659// index.d.ts
660export class DefineMethodObj {
661  defineMethodPropertiesExample: Function;
662}
663export class DefineStringObj {
664  defineStringPropertiesExample: string;
665}
666export class DefineGetterSetterObj {
667  getterCallback: Function;
668  setterCallback: Function;
669}
670export const defineMethodProperties: () => DefineMethodObj;
671export const defineStringProperties: () => DefineStringObj;
672export const createStringWithGetterSetter: () => DefineGetterSetterObj;
673```
674
675ArkTS侧示例代码
676
677```ts
678import hilog from '@ohos.hilog'
679import testNapi from 'libentry.so'
680// 定义method类型的属性
681hilog.info(0x0000, 'testTag', 'Test Node-API define_method_properties:%{public}d', testNapi.defineMethodProperties()
682  .defineMethodPropertiesExample());
683// 定义string类型的属性
684hilog.info(0x0000, 'testTag', 'Test Node-API define_string_properties::%{public}s ', testNapi.defineStringProperties()
685  .defineStringPropertiesExample);
686// getter和setter
687hilog.info(0x0000, 'testTag', 'Test Node-API get::%{public}s ', testNapi.createStringWithGetterSetter()
688  .getterCallback());
689hilog.info(0x0000, 'testTag', 'Test Node-API setter::%{public}s ', testNapi.createStringWithGetterSetter()
690  .setterCallback('set data'));
691```
692
693### napi_get_all_property_names
694
695用于获取传入的ArkTS对象的所有属性名。
696
697cpp部分代码
698
699```cpp
700#include "napi/native_api.h"
701
702static napi_value GetAllPropertyNames(napi_env env, napi_callback_info info)
703{
704    // 传入一个参数
705    size_t argc = 1;
706    napi_value args[1] = {nullptr};
707    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
708
709    // 获取给定对象的所有属性名称
710    napi_value result;
711    napi_status status = napi_get_all_property_names(env, args[0], napi_key_own_only, napi_key_writable,
712                                                     napi_key_numbers_to_strings, &result);
713    // 如果获取属性名失败,抛出一个错误
714    if (status != napi_ok) {
715        napi_throw_error(env, nullptr, "Node-API napi_get_all_property_names fail");
716        return nullptr;
717    }
718
719    return result;
720}
721```
722
723接口声明
724
725```ts
726// index.d.ts
727export const getAllPropertyNames : (obj: Object) => Array<string> | void;
728```
729
730ArkTS侧示例代码
731
732```ts
733import hilog from '@ohos.hilog'
734import testNapi from 'libentry.so'
735try {
736  class Obj {
737    data: number = 0
738    message: string = ""
739  }
740  let obj: Obj = { data: 0, message: "hello world"};
741  let propertyNames = testNapi.getAllPropertyNames(obj);
742  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_all_property_names: %{public}s', JSON.stringify(propertyNames));
743} catch (error) {
744  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_all_property_names error: %{public}s', error.message);
745}
746```
747
748以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
749
750```text
751// CMakeLists.txt
752add_definitions( "-DLOG_DOMAIN=0xd0d0" )
753add_definitions( "-DLOG_TAG=\"testTag\"" )
754target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
755```
756