1# 使用JSVM-API接口设置JavaScript对象的属性
2
3## 简介
4
5使用JSVM-API接口获取和设置JavaScript对象的属性。通过合理使用这些函数,实现更复杂的功能和逻辑。
6
7## 基本概念
8
9在JavaScript对象属性的相关开发中,需要处理JavaScript对象属性,确保正确地访问、设置、删除属性,并了解属性的继承关系和枚举特性。以下是一些关键概念:
10
11- **对象(Object)**:在JavaScript中,对象是一种复合数据类型,它允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值,而方法则是对象可以执行的操作。
12- **属性(Property)**:在JavaScript中,属性是对象特征的键值对。每个属性都有一个名字(也称为键或标识符)和一个值。属性的值可以是任意数据类型,包括基本类型、对象和函数。
13- **可枚举属性(EnumerableProperty)**:在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的,即内部 “可枚举” 标志设置为true或false。可枚举性决定了这个属性能否被 `for...in` 查找遍历到。
14- **自有属性(OwnProperty)**:自有属性是直接定义在对象上的属性,而不是从原型链上继承来的属性。
15
16## 接口说明
17
18| 接口                       | 功能说明                       |
19|----------------------------|--------------------------------|
20| OH_JSVM_GetPropertyNames   | 获取给定对象的所有可枚举属性名称,结果变量将存储一个包含所有可枚举属性名称的JavaScript数组 |
21| OH_JSVM_SetProperty        | 为给定对象设置一个属性 |
22| OH_JSVM_GetProperty        | 用给定的属性的名称,检索目标对象的属性 |
23| OH_JSVM_HasProperty        | 用给定的属性的名称,查询目标对象是否有此属性 |
24| OH_JSVM_DeleteProperty     | 用给定的属性的名称,删除目标对象属性 |
25| OH_JSVM_HasOwnProperty     | 判断给定Object中是否有名为key的own property。|
26| OH_JSVM_SetNamedProperty   | 用给定的属性的名称为目标对象设置属性,此方法等效于调用OH_JSVM_SetProperty, 其中,通过utf8Name传入的字符串用于创建JSVM_Value。|
27| OH_JSVM_GetNamedProperty   | 用给定的属性的名称,检索目标对象的属性,此方法等效于调用OH_JSVM_GetProperty, 其中,通过utf8Name传入的字符串用于创建JSVM_Value。|
28| OH_JSVM_HasNamedProperty   | 用给定的属性的名称,查询目标对象是否有此属性,此方法等效于使用从作为utf8Name传入的字符串创建的JSVM_Value调用OH_JSVM_HasProperty。|
29| OH_JSVM_DefineProperties   | 批量的向给定对象中定义属性 |
30| OH_JSVM_GetAllPropertyNames | 获取给定对象的所有可用属性名称,结果变量将存储一个包含所有可枚举属性名称的JavaScript数组 |
31
32## 使用示例
33
34JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++相关代码进行展示。
35
36### OH_JSVM_GetPropertyNames
37
38以字符串数组的形式获取对象的可枚举属性的名称,如果接口调用成功则返回JSVM_OK。
39
40cpp部分代码
41
42```cpp
43// OH_JSVM_GetPropertyNames的样例方法
44static JSVM_Value GetPropertyNames(JSVM_Env env, JSVM_CallbackInfo info)
45{
46    // 将obj作为参数传入
47    size_t argc = 1;
48    JSVM_Value args[1] = {nullptr};
49    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
50    // 以字符串数组的形式获取对象的可枚举属性的名称,以result传出
51    JSVM_Value result = nullptr;
52    JSVM_Status status = OH_JSVM_GetPropertyNames(env, args[0], &result);
53    if (status != JSVM_OK) {
54        OH_JSVM_ThrowError(env, nullptr, "Failed to get propertynames");
55        return nullptr;
56    } else {
57        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetPropertyNames success");
58    }
59    return result;
60}
61// GetPropertyNames注册回调
62static JSVM_CallbackStruct param[] = {
63    {.data = nullptr, .callback = GetPropertyNames},
64};
65static JSVM_CallbackStruct *method = param;
66// GetPropertyNames方法别名,供JS调用
67static JSVM_PropertyDescriptor descriptor[] = {
68    {"getPropertyNames", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
69};
70
71// 样例测试js
72const char *srcCallNative = R"JS(
73    let obj = '{ data: 0, message: "hello world"}';
74    let script = getPropertyNames(obj);
75)JS";
76```
77
78预期输出结果
79```ts
80JSVM OH_JSVM_GetPropertyNames success
81```
82
83### OH_JSVM_SetProperty
84
85将给定的属性与值设置入给定的Object
86
87cpp部分代码
88
89```cpp
90// OH_JSVM_SetProperty的样例方法
91static JSVM_Value SetProperty(JSVM_Env env, JSVM_CallbackInfo info)
92{
93    // 接收js侧传入的三个参数:第一个参数为想要设置的object,第二个参数为属性,第三个参数为属性对应的值
94    size_t argc = 3;
95    JSVM_Value args[3] = {nullptr};
96    JSVM_Status status = OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
97    if (status != JSVM_OK) {
98        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_GetCbInfo fail");
99        return nullptr;
100    }
101    // 通过调用OH_JSVM_SetProperty接口将属性与值设置入object如果失败,直接抛出错误
102    status = OH_JSVM_SetProperty(env, args[0], args[1], args[2]);
103    if (status != JSVM_OK) {
104        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_SetProperty fail");
105        return nullptr;
106    } else {
107        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SetProperty success");
108    }
109    // 将设置成功后的object返回出去
110    return args[0];
111}
112// SetProperty注册回调
113static JSVM_CallbackStruct param[] = {
114    {.data = nullptr, .callback = SetProperty},
115};
116static JSVM_CallbackStruct *method = param;
117// SetProperty方法别名,供JS调用
118static JSVM_PropertyDescriptor descriptor[] = {
119    {"setProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
120};
121
122// 样例测试js
123const char *srcCallNative = R"JS(
124    let obj = { data: 0, message: "hello world", 50: 1};
125    setProperty(obj, "code", "hi")
126)JS";
127```
128
129预期输出结果
130```ts
131JSVM OH_JSVM_SetProperty success
132```
133
134### OH_JSVM_GetProperty
135
136获取给定Object的给定属性对应的值
137
138cpp部分代码
139
140```cpp
141// OH_JSVM_GetProperty的样例方法
142static JSVM_Value GetProperty(JSVM_Env env, JSVM_CallbackInfo info)
143{
144    // 接收两个js传来的参数
145    size_t argc = 2;
146    JSVM_Value args[2] = {nullptr};
147    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
148    // 传入的第一个参数为要检测的object,第二个对象为要检测的属性,通过调用OH_JSVM_GetProperty接口获取对应的值
149    JSVM_Value result = nullptr;
150    JSVM_Status status = OH_JSVM_GetProperty(env, args[0], args[1], &result);
151    if (status != JSVM_OK) {
152        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_GetProperty fail");
153        return nullptr;
154    } else {
155        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetProperty success");
156    }
157    return result;
158}
159// GetProperty注册回调
160static JSVM_CallbackStruct param[] = {
161    {.data = nullptr, .callback = GetProperty},
162};
163static JSVM_CallbackStruct *method = param;
164// GetProperty方法别名,供JS调用
165static JSVM_PropertyDescriptor descriptor[] = {
166    {"getProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
167};
168
169// 样例测试js
170const char *srcCallNative = R"JS(
171    let obj = { data: 0, message: "hello world", 50: 1};
172    getProperty(obj, "message")
173)JS";
174```
175
176预期输出结果
177```ts
178JSVM OH_JSVM_GetProperty success
179```
180
181### OH_JSVM_HasProperty
182
183检查对象中是否存在指定的属性,可以避免访问不存在属性导致的异常或错误。
184
185cpp部分代码
186
187```cpp
188// OH_JSVM_HasProperty的样例方法
189static JSVM_Value HasProperty(JSVM_Env env, JSVM_CallbackInfo info)
190{
191    // 从js侧传入两个参数:第一个参数为要检验的对象,第二个参数为要检测是否存在对象的属性
192    size_t argc = 2;
193    JSVM_Value args[2] = {nullptr};
194    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
195    // 将参数传入OH_JSVM_HasProperty方法中,若接口调用成功则将结果转化为JSVM_Value类型抛出,否则抛出错误
196    bool result;
197    JSVM_Status status = OH_JSVM_HasProperty(env, args[0], args[1], &result);
198    if (status != JSVM_OK) {
199        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_HasProperty fail");
200        return nullptr;
201    } else {
202        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_HasProperty success:%{public}d", result);
203    }
204    // 若传入属性存在传入对象中,则输出true将结果转化为JSVM_Value类型抛出
205    JSVM_Value returnReslut = nullptr;
206    OH_JSVM_GetBoolean(env, result, &returnReslut);
207    return returnReslut;
208}
209// HasProperty注册回调
210static JSVM_CallbackStruct param[] = {
211    {.data = nullptr, .callback = HasProperty},
212};
213static JSVM_CallbackStruct *method = param;
214// HasProperty方法别名,供JS调用
215static JSVM_PropertyDescriptor descriptor[] = {
216    {"hasProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
217};
218
219// 样例测试js
220const char *srcCallNative = R"JS(
221    let obj = { data: 0, message: "hello world", 50: 1};
222    hasProperty(obj, "data")
223    hasProperty(obj, 0)
224)JS";
225```
226
227预期输出结果
228```ts
229// hasProperty(obj, "data")输出
230JSVM OH_JSVM_HasProperty success:1
231// hasProperty(obj, 0)输出
232JSVM OH_JSVM_HasProperty success:0
233```
234
235### OH_JSVM_DeleteProperty
236
237尝试从给定的Object中删除由key指定的属性,并返回操作的结果。
238如果对象是一个不可扩展的对象,或者属性是不可配置的,则可能无法删除该属性。
239
240cpp部分代码
241
242```cpp
243// OH_JSVM_DeleteProperty的样例方法
244static JSVM_Value DeleteProperty(JSVM_Env env, JSVM_CallbackInfo info)
245{
246    // 获取js侧传入的两个参数
247    size_t argc = 2;
248    JSVM_Value args[2] = {nullptr};
249    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
250    JSVM_ValueType valueType;
251    OH_JSVM_Typeof(env, args[0], &valueType);
252    if (valueType != JSVM_OBJECT) {
253        OH_JSVM_ThrowError(env, nullptr, "Expects an object as argument.");
254        return nullptr;
255    }
256    // 从传入的Object对象中删除指定属性,返回是否删除成功的bool结果值
257    bool result = false;
258    JSVM_Status status = OH_JSVM_DeleteProperty(env, args[0], args[1], &result);
259    if (status != JSVM_OK) {
260        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_DeleteProperty failed");
261        return nullptr;
262    } else {
263        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_DeleteProperty success:%{public}d", result);
264    }
265    // 将bool结果转换为JSVM_value并返回
266    JSVM_Value ret;
267    OH_JSVM_GetBoolean(env, result, &ret);
268    return ret;
269}
270// DeleteProperty注册回调
271static JSVM_CallbackStruct param[] = {
272    {.data = nullptr, .callback = DeleteProperty},
273};
274static JSVM_CallbackStruct *method = param;
275// DeleteProperty方法别名,供JS调用
276static JSVM_PropertyDescriptor descriptor[] = {
277    {"deleteProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
278};
279
280// 样例测试js
281const char *srcCallNative = R"JS(
282    let obj = { data: 0, message: "hello world", 50: 1};
283    deleteProperty(obj, "message")
284)JS";
285```
286
287预期输出结果
288```ts
289JSVM OH_JSVM_DeleteProperty success:1
290```
291
292### OH_JSVM_HasOwnProperty
293
294用于检查传入的Object是否具有自己的命名属性,不包括从原型链上继承的属性。
295
296cpp部分代码
297
298```cpp
299// OH_JSVM_HasOwnProperty的样例方法
300static JSVM_Value HasOwnProperty(JSVM_Env env, JSVM_CallbackInfo info)
301{
302    // 获取js侧传入的两个参数
303    size_t argc = 2;
304    JSVM_Value args[2] = {nullptr};
305    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
306    // 检查第一个参数是否为对象
307    JSVM_ValueType valueType1;
308    OH_JSVM_Typeof(env, args[0], &valueType1);
309    if (valueType1 != JSVM_OBJECT) {
310        OH_JSVM_ThrowError(env, nullptr, "First argument must be an object.");
311        return nullptr;
312    }
313    // 检查第二个参数是否为string
314    JSVM_ValueType valuetype2;
315    OH_JSVM_Typeof(env, args[1], &valuetype2);
316    if (valuetype2 != JSVM_STRING ) {
317        OH_JSVM_ThrowError(env, nullptr, "Second argument must be a string.");
318        return nullptr;
319    }
320    // 检查对象是否具有指定属性,结果存储在hasProperty中
321    bool hasProperty;
322    JSVM_Status status = OH_JSVM_HasOwnProperty(env, args[0], args[1], &hasProperty);
323    if (status != JSVM_OK) {
324        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_HasOwnProperty failed");
325        return nullptr;
326    } else {
327        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_HasOwnProperty success:%{public}d", hasProperty);
328    }
329    // 将bool结果转换为JSVM_Value并返回
330    JSVM_Value result;
331    OH_JSVM_GetBoolean(env, hasProperty, &result);
332    return result;
333}
334// HasOwnProperty注册回调
335static JSVM_CallbackStruct param[] = {
336    {.data = nullptr, .callback = HasOwnProperty},
337};
338static JSVM_CallbackStruct *method = param;
339// HasOwnProperty方法别名,供JS调用
340static JSVM_PropertyDescriptor descriptor[] = {
341    {"hasOwnProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
342};
343
344// 样例测试js
345const char *srcCallNative = R"JS(
346    let obj = { data: 0, message: "hello world", 50: 1};
347    hasOwnProperty(obj, "message")
348    hasOwnProperty(obj, "__defineGetter__")
349)JS";
350```
351
352预期输出结果
353```ts
354// hasOwnProperty(obj, "message")输出
355JSVM OH_JSVM_HasOwnProperty success:1
356// hasOwnProperty(obj, "__defineGetter__")输出
357// `__defineGetter__`为Object原型方法,非OwnProperty,预期返回0
358JSVM OH_JSVM_HasOwnProperty success:0
359```
360
361### OH_JSVM_SetNamedProperty
362
363用于在传入的Javascript对象上设置一个命名属性。
364
365cpp部分代码
366
367```cpp
368// OH_JSVM_SetNamedProperty的样例方法
369static JSVM_Value SetNamedProperty(JSVM_Env env, JSVM_CallbackInfo info)
370{
371    // 获取js侧传入的一个参数
372    size_t argc = 1;
373    JSVM_Value str;
374    char strKey[32] = "";
375    OH_JSVM_GetCbInfo(env, info, &argc, &str, nullptr, nullptr);
376    // 获取传入参数字符串并存储在strKey中
377    size_t keyLength;
378    OH_JSVM_GetValueStringUtf8(env, str, strKey, 32, &keyLength);
379    // 创建一个新对象
380    JSVM_Value newObj;
381    OH_JSVM_CreateObject(env, &newObj);
382    // 设置整数值1234为属性值
383    int32_t value = 1234;
384    JSVM_Value numValue;
385    OH_JSVM_CreateInt32(env, value, &numValue);
386    // 将整数值与指定属性名关联
387    JSVM_Status status = OH_JSVM_SetNamedProperty(env, newObj, strKey, numValue);
388    if (status != JSVM_OK) {
389        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_SetNamedProperty failed");
390        return nullptr;
391    } else {
392        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SetNamedProperty success");
393    }
394    // 返回新创建并设置命名属性的对象
395    return newObj;
396}
397// SetNamedProperty注册回调
398static JSVM_CallbackStruct param[] = {
399    {.data = nullptr, .callback = SetNamedProperty},
400};
401static JSVM_CallbackStruct *method = param;
402// SetNamedProperty方法别名,供JS调用
403static JSVM_PropertyDescriptor descriptor[] = {
404    {"setNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
405};
406
407// 样例测试js
408const char *srcCallNative = R"JS(
409    setNamedProperty("message")
410)JS";
411```
412
413预期输出结果
414```ts
415JSVM OH_JSVM_SetNamedProperty success
416```
417
418### OH_JSVM_GetNamedProperty
419
420用于从Javascript对象中获取命名属性的值。
421
422cpp部分代码
423
424```cpp
425// OH_JSVM_GetNamedProperty的样例方法
426static JSVM_Value GetNamedProperty(JSVM_Env env, JSVM_CallbackInfo info)
427{
428    // 获取js侧传入的两个参数
429    size_t argc = 2;
430    JSVM_Value args[2] = {nullptr};
431    char strKey[32] = "";
432    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
433    // 获取要获取的属性名
434    size_t keyLength;
435    OH_JSVM_GetValueStringUtf8(env, args[1], strKey, 32, &keyLength);
436    // 获取指定属性的值并存储在result中
437    JSVM_Value result;
438    JSVM_Status status = OH_JSVM_GetNamedProperty(env, args[0], strKey, &result);
439    if (status != JSVM_OK) {
440        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_GetNamedProperty failed");
441        return nullptr;
442    } else {
443        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNamedProperty success");
444    }
445    return result;
446}
447// GetNamedProperty注册回调
448static JSVM_CallbackStruct param[] = {
449    {.data = nullptr, .callback = GetNamedProperty},
450};
451static JSVM_CallbackStruct *method = param;
452// GetNamedProperty方法别名,供JS调用
453static JSVM_PropertyDescriptor descriptor[] = {
454    {"getNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
455};
456
457// 样例测试js
458const char *srcCallNative = R"JS(
459    let obj = { data: 0, message: "hello world", 50: 1};
460    getNamedProperty(obj, "message")
461)JS";
462```
463
464预期输出结果
465```ts
466JSVM OH_JSVM_GetNamedProperty success
467```
468
469### OH_JSVM_HasNamedProperty
470
471用于检查Javascript对象中是否包含指定的命名属性。
472
473cpp部分代码
474
475```cpp
476// OH_JSVM_HasNamedProperty的样例方法
477static JSVM_Value HasNamedProperty(JSVM_Env env, JSVM_CallbackInfo info)
478{
479    // 获取js侧传入的两个参数
480    size_t argc = 2;
481    JSVM_Value args[2] = {nullptr};
482    char strKey[32] = "";
483    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
484    // 获取要检查的属性名
485    size_t keyLength;
486    OH_JSVM_GetValueStringUtf8(env, args[1], strKey, 32, &keyLength);
487    // 检查对象是否具有指定命名的属性,并将结果存储在hasProperty中
488    bool hasProperty = false;
489    JSVM_Status status = OH_JSVM_HasNamedProperty(env, args[0], strKey, &hasProperty);
490    if (status != JSVM_OK) {
491        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_HasNamedProperty failed");
492        return nullptr;
493    } else {
494        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_HasNamedProperty success:%{public}d", hasProperty);
495    }
496    // 将bool结果转换为JSVM_Value并返回
497    JSVM_Value result;
498    OH_JSVM_GetBoolean(env, hasProperty, &result);
499    return result;
500}
501// HasNamedProperty注册回调
502static JSVM_CallbackStruct param[] = {
503    {.data = nullptr, .callback = HasNamedProperty},
504};
505static JSVM_CallbackStruct *method = param;
506// HasNamedProperty方法别名,供JS调用
507static JSVM_PropertyDescriptor descriptor[] = {
508    {"hasNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
509};
510
511// 样例测试js
512const char *srcCallNative = R"JS(
513    let obj = { data: 0, message: "hello world", 50: 1};
514    hasNamedProperty(obj, "message")
515)JS";
516```
517
518预期输出结果
519```ts
520JSVM OH_JSVM_HasNamedProperty success:1
521```
522
523### OH_JSVM_DefineProperties
524
525用于定义对象的自定义属性,可一次性为对象设置多个属性。
526
527cpp部分代码
528
529```cpp
530// 属性描述符列表中defineMethodPropertiesExample属性的回调函数
531static JSVM_Value DefineMethodPropertiesExample(JSVM_Env env, JSVM_CallbackInfo info)
532{
533    int32_t propValue = 26;
534    JSVM_Value returnValue;
535    OH_JSVM_CreateInt32(env, propValue, &returnValue);
536    return returnValue;
537}
538// 属性描述符列表中getterCallback属性的回调函数
539static JSVM_Value GetterCallback(JSVM_Env env, JSVM_CallbackInfo info)
540{
541    JSVM_Value result;
542    const char *str = "Hello world!";
543    size_t length = strlen(str);
544    // 创建属性的值
545    OH_JSVM_CreateStringUtf8(env, str, length, &result);
546    return result;
547}
548
549// 执行JavaScript字符串的函数
550static JSVM_Value RunScriptAndLogResult(JSVM_Env env, const std::string &srcCode) {
551    JSVM_Value sourceCodeValue;
552    OH_JSVM_CreateStringUtf8(env, srcCode.c_str(), srcCode.size(), &sourceCodeValue);
553    JSVM_Script script;
554    // 编译JavaScript代码字符串并返回编译后的脚本
555    OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
556    JSVM_Value jsVmResult;
557    // 执行JavaScript代码字符串
558    OH_JSVM_RunScript(env, script, &jsVmResult);
559    return jsVmResult;
560}
561
562// OH_JSVM_DefineProperties的样例方法
563static JSVM_Value DefineProperties(JSVM_Env env, JSVM_CallbackInfo info) {
564    // 接受一个JavaScript侧传入的空object
565    size_t argc = 1;
566    JSVM_Value argv[1] = {nullptr};
567    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
568    // 创建一个string类型的属性值
569    JSVM_Value stringValue;
570    OH_JSVM_CreateStringUtf8(env, "Hello!", JSVM_AUTO_LENGTH, &stringValue);
571    // 创建属性描述符对应的回调函数列表
572    JSVM_CallbackStruct param[] = {
573        {.data = nullptr, .callback = DefineMethodPropertiesExample},
574        {.data = nullptr, .callback = GetterCallback},
575
576    };
577    // 创建属性描述符列表,不同类型属性值添加位置参考JSVM_PropertyDescriptor定义
578    JSVM_PropertyDescriptor descriptor[] = {
579        // 定义method类型的属性值
580        {"defineMethodPropertiesExample", nullptr, &param[0], nullptr, nullptr, nullptr, JSVM_DEFAULT},
581        // 定义string类型的属性值
582        {"defineStringPropertiesExample", nullptr, nullptr, nullptr, nullptr, stringValue, JSVM_DEFAULT},
583        // 定义getter类型的属性值
584        {"getterCallback", nullptr, nullptr, &param[1], nullptr, nullptr,JSVM_DEFAULT}};
585    // 根据属性描述符列表为obj对象创建属性
586    JSVM_Status statusProperty;
587    statusProperty = OH_JSVM_DefineProperties(env, *argv, sizeof(descriptor) / sizeof(descriptor[0]), descriptor);
588    if (statusProperty != JSVM_OK) {
589        OH_JSVM_ThrowError(env, nullptr, "JSVM DefineProperties fail");
590        return nullptr;
591    }
592    // 调用obj对象中添加的属性
593    // 运行obj.defineMethodPropertiesExample()并将结果返回给JavaScript
594    static std::string srcMethod;
595    srcMethod = R"JS(obj.defineMethodPropertiesExample();)JS";
596    JSVM_Value jsVmResult = RunScriptAndLogResult(env, srcMethod);
597    if (jsVmResult != nullptr) {
598        int32_t number;
599        OH_JSVM_GetValueInt32(env, jsVmResult, &number);
600        OH_LOG_INFO(LOG_APP, "JSVM DefineMethodPropertiesExample success:%{public}d", number);
601    }
602    // 运行obj.defineStringPropertiesExample()并将结果返回给JavaScript
603    static std::string srcString;
604    srcString = R"JS(obj.defineStringPropertiesExample;)JS";
605    JSVM_Value jsVmResult1 = RunScriptAndLogResult(env, srcString);
606    if (jsVmResult1 != nullptr) {
607        size_t length = 0;
608        OH_JSVM_GetValueStringUtf8(env, jsVmResult1, nullptr, 0, &length);
609        char *buf = (char *)malloc(length + 1);
610        OH_JSVM_GetValueStringUtf8(env, jsVmResult1, buf, length + 1, &length);
611        OH_LOG_INFO(LOG_APP, "JSVM defineStringPropertiesExample success:%{public}s", buf);
612        free(buf);
613    }
614    // 调用obj的getterCallback()并将结果字符串返回给JavaScript
615    static std::string srcGetter;
616    srcGetter = R"JS(obj.getterCallback;)JS";
617    JSVM_Value jsVmResult2 = RunScriptAndLogResult(env, srcGetter);
618    if (jsVmResult2 != nullptr) {
619        size_t length = 0;
620        OH_JSVM_GetValueStringUtf8(env, jsVmResult2, nullptr, 0, &length);
621        char *buf = (char *)malloc(length + 1);
622        OH_JSVM_GetValueStringUtf8(env, jsVmResult2, buf, length + 1, &length);
623        OH_LOG_INFO(LOG_APP, "JSVM getterCallback success:%{public}s", buf);
624        free(buf);
625    }
626    return jsVmResult;
627}
628
629// DefineProperties注册回调
630static JSVM_CallbackStruct param[] = {
631    {.data = nullptr, .callback = DefineProperties},
632};
633static JSVM_CallbackStruct *method = param;
634// DefineProperties方法别名,供JS调用
635static JSVM_PropertyDescriptor descriptor[] = {
636    {"defineProperties", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
637};
638
639// 样例测试js
640const char *srcCallNative = R"JS(
641    let obj = {};
642    defineProperties(obj)
643)JS";
644```
645
646预期输出结果
647```ts
648JSVM DefineMethodPropertiesExample success:26
649JSVM defineStringPropertiesExample success:Hello!
650JSVM getterCallback success:Hello world!
651```
652
653### OH_JSVM_GetAllPropertyNames
654
655获取给定对象的所有可用属性名称, 结果变量将存储一个包含所有可枚举属性名称的JavaScript数组。
656
657cpp部分代码
658
659```cpp
660// OH_JSVM_GetAllPropertyNames的样例方法
661static JSVM_Value GetAllPropertyNames(JSVM_Env env, JSVM_CallbackInfo info)
662{
663    // // 获取js侧传入的一个参数
664    size_t argc = 1;
665    JSVM_Value args[1];
666    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
667    // 获取给定对象的所有属性名称(自有属性)
668    JSVM_Value result;
669    JSVM_Status status = OH_JSVM_GetAllPropertyNames(env, args[0],
670                                         JSVM_KeyCollectionMode::JSVM_KEY_OWN_ONLY,
671                                         JSVM_KeyFilter::JSVM_KEY_WRITABLE,
672                                         JSVM_KeyConversion::JSVM_KEY_NUMBERS_TO_STRINGS, &result);
673    if (status != JSVM_OK) {
674        OH_JSVM_ThrowError(env, nullptr, "Failed to get allpropertynames");
675        return nullptr;
676    } else {
677        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetAllPropertyNames success");
678    }
679    return result;
680}
681// GetAllPropertyNames注册回调
682static JSVM_CallbackStruct param[] = {
683    {.data = nullptr, .callback = GetAllPropertyNames},
684};
685static JSVM_CallbackStruct *method = param;
686// GetAllPropertyNames方法别名,供JS调用
687static JSVM_PropertyDescriptor descriptor[] = {
688    {"getAllPropertyNames", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
689};
690
691// 样例测试js
692const char *srcCallNative = R"JS(
693    let obj = '{ data: 0, message: "hello world", 50: 1}';
694    let script = getAllPropertyNames(obj);
695)JS";
696```
697
698预期输出结果
699```ts
700JSVM OH_JSVM_GetAllPropertyNames success
701```
702