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