1# Setting JS Object Properties Using JSVM-API
2
3## Introduction
4
5This topic walks you through on how to obtain and set properties of a JavaScript (JS) object using JSVM-API. Properly using these APIs help to implement more complex functionalities and logic.
6
7## Basic Concepts
8
9Before working with JS objects using JSVM-API, you need to understand the following concepts:
10
11- Object: a composite data type that allows values of different types in an independent entity in JS. An object is a collection of properties and methods. A property is a value associated with the object, and a method is an operation that the object can perform.
12- Property: a feature, in the key-value format, of an object in JS. Each property has a name (key or identifier) and a value. The property value can be of any data type, including the basic type, object, and function.
13- Enumerable property: a property in JS with **enumerable** set to **true**. An enumerable property can be traversed by **for...in**.
14- Own property: a property defined for an object rather than inherited from the prototype chain.
15
16## Available APIs
17
18| API                      | Description                      |
19|----------------------------|--------------------------------|
20| OH_JSVM_GetPropertyNames   | Obtains the names of all enumerable properties of a JS object as a JS array.|
21| OH_JSVM_SetProperty        | Sets a property for a JS object.|
22| OH_JSVM_GetProperty        | Obtains a property from a JS object.|
23| OH_JSVM_HasProperty        | Checks whether a JS object has the specified property.|
24| OH_JSVM_DeleteProperty     | Deletes a property from a JS object.|
25| OH_JSVM_HasOwnProperty     | Checks whether an object has the own property specified by **key**.|
26| OH_JSVM_SetNamedProperty   | Sets a property with the given property name for a JS object. This API is equivalent to calling **OH_JSVM_SetNamedProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
27| OH_JSVM_GetNamedProperty   | Obtains a property from a JS object. This API is equivalent to calling **OH_JSVM_GetNamedProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
28| OH_JSVM_HasNamedProperty   | Checks whether a JS object has the specified property. This API is equivalent to calling **OH_JSVM_HasProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
29| OH_JSVM_DefineProperties   | Defines multiple properties for a JS object.|
30| OH_JSVM_GetAllPropertyNames | Obtains the names of all available properties of a JS object as a JS array.|
31
32## Example
33
34If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in setting properties.
35
36### OH_JSVM_GetPropertyNames
37
38Use **OH_JSVM_GetPropertyNames** to obtain names of all enumerable properties of a JS object in the form of a string array. If the operation is successful, **JSVM_OK** is returned.
39
40CPP code:
41
42```cpp
43// Define OH_JSVM_GetPropertyNames.
44static JSVM_Value GetPropertyNames(JSVM_Env env, JSVM_CallbackInfo info)
45{
46    // Pass in obj as a parameter.
47    size_t argc = 1;
48    JSVM_Value args[1] = {nullptr};
49    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
50    // Obtain the names of all the enumerable properties of the object in the form of a string array and output the string array in 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// Register the GetPropertyNames callback.
62static JSVM_CallbackStruct param[] = {
63    {.data = nullptr, .callback = GetPropertyNames},
64};
65static JSVM_CallbackStruct *method = param;
66// Set a property descriptor named getPropertyNames and associate it with a callback. This allows the CreateStringLatin1 callback to be called from JS.
67static JSVM_PropertyDescriptor descriptor[] = {
68    {"getPropertyNames", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
69};
70
71// Call the C++ code from JS.
72const char *srcCallNative = R"JS(
73    let obj = '{ data: 0, message: "hello world"}';
74    let script = getPropertyNames(obj);
75)JS";
76```
77
78**Expected output**
79```ts
80JSVM OH_JSVM_GetPropertyNames success
81```
82
83### OH_JSVM_SetProperty
84
85Use **OH_JSVM_SetProperty** to set a property for an object.
86
87CPP code:
88
89```cpp
90// Define OH_JSVM_SetProperty.
91static JSVM_Value SetProperty(JSVM_Env env, JSVM_CallbackInfo info)
92{
93    // Obtain the parameters passed from JS. The first parameter specifies the object, the second parameter specifies the property name, and the third parameter specifies the property value to set.
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    // Call OH_JSVM_SetProperty to set the property name and value to the object. If the operation fails, an error is thrown.
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    // Return the object that is successfully set.
110    return args[0];
111}
112// Register the SetProperty callback.
113static JSVM_CallbackStruct param[] = {
114    {.data = nullptr, .callback = SetProperty},
115};
116static JSVM_CallbackStruct *method = param;
117// Set a property descriptor named setProperty and associate it with a callback. This allows the SetProperty callback to be called from JS.
118static JSVM_PropertyDescriptor descriptor[] = {
119    {"setProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
120};
121
122// Call the C++ code from 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**Expected output**
130```ts
131JSVM OH_JSVM_SetProperty success
132```
133
134### OH_JSVM_GetProperty
135
136Use **OH_JSVM_GetProperty** to obtain a property value of a JS object based on the property name.
137
138CPP code:
139
140```cpp
141// Define OH_JSVM_GetProperty.
142static JSVM_Value GetProperty(JSVM_Env env, JSVM_CallbackInfo info)
143{
144    // Obtain the two parameters passed from JS.
145    size_t argc = 2;
146    JSVM_Value args[2] = {nullptr};
147    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
148    // The first parameter specifies the target object, and the second specifies the property name. Call OH_JSVM_GetProperty to obtain the value of the property.
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// Register the GetProperty callback.
160static JSVM_CallbackStruct param[] = {
161    {.data = nullptr, .callback = GetProperty},
162};
163static JSVM_CallbackStruct *method = param;
164// Set a property descriptor named getProperty and associate it with a callback. This allows the GetProperty callback to be called from JS.
165static JSVM_PropertyDescriptor descriptor[] = {
166    {"getProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
167};
168
169// Call the C++ code from 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**Expected output**
177```ts
178JSVM OH_JSVM_GetProperty success
179```
180
181### OH_JSVM_HasProperty
182
183Use **OH_JSVM_HasProperty** to check whether an object has the specified property. This can prevent the exception or error caused by access to a property that does not exist.
184
185CPP code:
186
187```cpp
188// Define OH_JSVM_HasProperty.
189static JSVM_Value HasProperty(JSVM_Env env, JSVM_CallbackInfo info)
190{
191    // Pass in two parameters from JS. The first parameter specifies the target object, and the second parameter specifies the property to check.
192    size_t argc = 2;
193    JSVM_Value args[2] = {nullptr};
194    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
195    // Pass the parameters to OH_JSVM_HasProperty. If the API is successfully called, convert the result to JSVM_Value and return JSVM_Value. Otherwise, throw an error.
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    // If the property exists in the object, output true, convert the result to JSVM_Value, and return JSVM_Value.
205    JSVM_Value returnReslut = nullptr;
206    OH_JSVM_GetBoolean(env, result, &returnReslut);
207    return returnReslut;
208}
209// Register the HasProperty callback.
210static JSVM_CallbackStruct param[] = {
211    {.data = nullptr, .callback = HasProperty},
212};
213static JSVM_CallbackStruct *method = param;
214// Set a property descriptor named hasProperty and associate it with a callback. This allows the HasProperty callback to be called from JS.
215static JSVM_PropertyDescriptor descriptor[] = {
216    {"hasProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
217};
218
219// Call the C++ code from 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**Expected output**
228```ts
229// Output of hasProperty (obj, "data").
230JSVM OH_JSVM_HasProperty success:1
231// Output of hasProperty (obj, 0).
232JSVM OH_JSVM_HasProperty success:0
233```
234
235### OH_JSVM_DeleteProperty
236
237Use **OH_JSVM_DeleteProperty** to delete the property specified by **key** from an object.
238If the object is a non-extensible object or the property is not configurable, the property cannot be deleted.
239
240CPP code:
241
242```cpp
243// Define OH_JSVM_DeleteProperty.
244static JSVM_Value DeleteProperty(JSVM_Env env, JSVM_CallbackInfo info)
245{
246    // Obtain the two parameters passed from 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    // Delete the specified property from the object and return a bool value indicating whether the deletion is successful.
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    // Convert the bool value to JSVM_value and return JSVM_value.
266    JSVM_Value ret;
267    OH_JSVM_GetBoolean(env, result, &ret);
268    return ret;
269}
270// Register the DeleteProperty callback.
271static JSVM_CallbackStruct param[] = {
272    {.data = nullptr, .callback = DeleteProperty},
273};
274static JSVM_CallbackStruct *method = param;
275// Set a property descriptor named deleteProperty and associate it with a callback. This allows the DeleteProperty callback to be called from JS.
276static JSVM_PropertyDescriptor descriptor[] = {
277    {"deleteProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
278};
279
280// Call the C++ code from 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**Expected output**
288```ts
289JSVM OH_JSVM_DeleteProperty success:1
290```
291
292### OH_JSVM_HasOwnProperty
293
294Use **OH_JSVM_HasOwnProperty** to check whether a JS object has its own property.
295
296CPP code:
297
298```cpp
299// Define OH_JSVM_HasOwnProperty.
300static JSVM_Value HasOwnProperty(JSVM_Env env, JSVM_CallbackInfo info)
301{
302    // Obtain the two parameters passed from JS.
303    size_t argc = 2;
304    JSVM_Value args[2] = {nullptr};
305    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
306    // Check whether the first parameter is an object.
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    // Check whether the second parameter is a 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    // Check whether the object has the specified property. The result is in 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    // Convert the bool value to JSVM_Value and return JSVM_value.
330    JSVM_Value result;
331    OH_JSVM_GetBoolean(env, hasProperty, &result);
332    return result;
333}
334// Register the HasOwnProperty callback.
335static JSVM_CallbackStruct param[] = {
336    {.data = nullptr, .callback = HasOwnProperty},
337};
338static JSVM_CallbackStruct *method = param;
339// Set a property descriptor named hasOwnProperty and associate it with a callback. This allows the HasOwnProperty callback to be called from JS.
340static JSVM_PropertyDescriptor descriptor[] = {
341    {"hasOwnProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
342};
343
344// Call the C++ code from 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**Expected output**
353```ts
354// hasOwnProperty (obj, "message") output
355JSVM OH_JSVM_HasOwnProperty success:1
356// hasOwnProperty(obj, "__defineGetter__") output
357// `__defineGetter__` is the prototype method of the object, not OwnProperty. The expected return value is 0.
358JSVM OH_JSVM_HasOwnProperty success:0
359```
360
361### OH_JSVM_SetNamedProperty
362
363Use **OH_JSVM_SetNamedProperty** to set a property for a JS object.
364
365CPP code:
366
367```cpp
368// Define OH_JSVM_SetNamedProperty.
369static JSVM_Value SetNamedProperty(JSVM_Env env, JSVM_CallbackInfo info)
370{
371    // Obtain the parameter passed from 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    // Obtain the string passed in and store it in strKey.
377    size_t keyLength;
378    OH_JSVM_GetValueStringUtf8(env, str, strKey, 32, &keyLength);
379    // Create an object.
380    JSVM_Value newObj;
381    OH_JSVM_CreateObject(env, &newObj);
382    // Set the property value to 1234.
383    int32_t value = 1234;
384    JSVM_Value numValue;
385    OH_JSVM_CreateInt32(env, value, &numValue);
386    // Associate the integer value with the property name.
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    // Return the newly created object with the property set.
395    return newObj;
396}
397// Register the SetNamedProperty callback.
398static JSVM_CallbackStruct param[] = {
399    {.data = nullptr, .callback = SetNamedProperty},
400};
401static JSVM_CallbackStruct *method = param;
402// Set a property descriptor named SetNamedProperty and associate it with a callback. This allows the SetNamedProperty callback to be called from JS.
403static JSVM_PropertyDescriptor descriptor[] = {
404    {"setNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
405};
406
407// Call the C++ code from JS.
408const char *srcCallNative = R"JS(
409    setNamedProperty("message")
410)JS";
411```
412
413**Expected output**
414```ts
415JSVM OH_JSVM_SetNamedProperty success
416```
417
418### OH_JSVM_GetNamedProperty
419
420Use **OH_JSVM_GetNamedProperty** to obtain the value of the specified property from a JS object.
421
422CPP code:
423
424```cpp
425// Define OH_JSVM_GetNamedProperty.
426static JSVM_Value GetNamedProperty(JSVM_Env env, JSVM_CallbackInfo info)
427{
428    // Obtain the two parameters passed from 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    // Obtain the name of the property to obtain.
434    size_t keyLength;
435    OH_JSVM_GetValueStringUtf8(env, args[1], strKey, 32, &keyLength);
436    // Obtain the value of the property and store it in 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// Register the GetNamedProperty callback.
448static JSVM_CallbackStruct param[] = {
449    {.data = nullptr, .callback = GetNamedProperty},
450};
451static JSVM_CallbackStruct *method = param;
452// Set a property descriptor named getNamedProperty and associate it with a callback. This allows the GetNamedProperty callback to be called from JS.
453static JSVM_PropertyDescriptor descriptor[] = {
454    {"getNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
455};
456
457// Call the C++ code from 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**Expected output**
465```ts
466JSVM OH_JSVM_GetNamedProperty success
467```
468
469### OH_JSVM_HasNamedProperty
470
471Use **OH_JSVM_HasNamedProperty** to check whether a JS object contains the specified property.
472
473CPP code:
474
475```cpp
476// Define OH_JSVM_HasNamedProperty.
477static JSVM_Value HasNamedProperty(JSVM_Env env, JSVM_CallbackInfo info)
478{
479    // Obtain the two parameters passed from 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    // Obtain the property name.
485    size_t keyLength;
486    OH_JSVM_GetValueStringUtf8(env, args[1], strKey, 32, &keyLength);
487    // Check whether the object has the specified property. The result is in 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    // Convert the bool value to JSVM_Value and return JSVM_value.
497    JSVM_Value result;
498    OH_JSVM_GetBoolean(env, hasProperty, &result);
499    return result;
500}
501// Register the HasNamedProperty callback.
502static JSVM_CallbackStruct param[] = {
503    {.data = nullptr, .callback = HasNamedProperty},
504};
505static JSVM_CallbackStruct *method = param;
506// Set a property descriptor named hasNamedProperty and associate it with a callback. This allows the HasNamedProperty callback to be called from JS.
507static JSVM_PropertyDescriptor descriptor[] = {
508    {"hasNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
509};
510
511// Call the C++ code from 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**Expected output**
519```ts
520JSVM OH_JSVM_HasNamedProperty success:1
521```
522
523### OH_JSVM_DefineProperties
524
525Use **OH_JSVM_DefineProperties** to customize one or more properties for an object.
526
527CPP code:
528
529```cpp
530// Callback for defineMethodPropertiesExample in the property descriptor list.
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// Callback for getterCallback in the property descriptor list.
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    // Create property values.
545    OH_JSVM_CreateStringUtf8(env, str, length, &result);
546    return result;
547}
548
549// Function to execute a JS string.
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    // Compile the JS code string and return the compiled script.
555    OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
556    JSVM_Value jsVmResult;
557    // Execute the JS script.
558    OH_JSVM_RunScript(env, script, &jsVmResult);
559    return jsVmResult;
560}
561
562// Define OH_JSVM_DefineProperties.
563static JSVM_Value DefineProperties(JSVM_Env env, JSVM_CallbackInfo info) {
564    // Obtain an empty object passed from JS.
565    size_t argc = 1;
566    JSVM_Value argv[1] = {nullptr};
567    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
568    // Create a property value of the string type.
569    JSVM_Value stringValue;
570    OH_JSVM_CreateStringUtf8(env, "Hello!", JSVM_AUTO_LENGTH, &stringValue);
571    // Create the callback lists corresponding to the property descriptors.
572    JSVM_CallbackStruct param[] = {
573        {.data = nullptr, .callback = DefineMethodPropertiesExample},
574        {.data = nullptr, .callback = GetterCallback},
575
576    };
577    // Create a property descriptor list. For details, see the definition of JSVM_PropertyDescriptor.
578    JSVM_PropertyDescriptor descriptor[] = {
579        // Define a property value of the method type.
580        {"defineMethodPropertiesExample", nullptr, &param[0], nullptr, nullptr, nullptr, JSVM_DEFAULT},
581        // Define the property value of the string type.
582        {"defineStringPropertiesExample", nullptr, nullptr, nullptr, nullptr, stringValue, JSVM_DEFAULT},
583        // Define the property value of the getter type.
584        {"getterCallback", nullptr, nullptr, &param[1], nullptr, nullptr,JSVM_DEFAULT}};
585    // Create properties for the obj object based on the property descriptor list.
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    // Call the properties added to the obj object.
593    // Run obj.defineMethodPropertiesExample() and return the result to JS.
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    // Run obj.defineStringPropertiesExample() and return the result to JS.
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    }
613    // Call getterCallback() of obj and return the result string to JS.
614    static std::string srcGetter;
615    srcGetter = R"JS(obj.getterCallback;)JS";
616    JSVM_Value jsVmResult2 = RunScriptAndLogResult(env, srcGetter);
617    if (jsVmResult2 != nullptr) {
618        size_t length = 0;
619        OH_JSVM_GetValueStringUtf8(env, jsVmResult2, nullptr, 0, &length);
620        char *buf = (char *)malloc(length + 1);
621        OH_JSVM_GetValueStringUtf8(env, jsVmResult2, buf, length + 1, &length);
622        OH_LOG_INFO(LOG_APP, "JSVM getterCallback success:%{public}s", buf);
623    }
624    return jsVmResult;
625}
626
627// Register the DefineProperties callback.
628static JSVM_CallbackStruct param[] = {
629    {.data = nullptr, .callback = DefineProperties},
630};
631static JSVM_CallbackStruct *method = param;
632// Set a property descriptor named defineProperties and associate it with a callback. This allows the DefineProperties callback to be called from JS.
633static JSVM_PropertyDescriptor descriptor[] = {
634    {"defineProperties", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
635};
636
637// Call the C++ code from JS.
638const char *srcCallNative = R"JS(
639    let obj = {};
640    defineProperties(obj)
641)JS";
642```
643
644**Expected output**
645```ts
646JSVM DefineMethodPropertiesExample success:26
647JSVM defineStringPropertiesExample success:Hello!
648JSVM getterCallback success:Hello world!
649```
650
651### OH_JSVM_GetAllPropertyNames
652
653Use **OH_JSVM_GetAllPropertyNames** to obtain the names of all available properties of a JS object as a JS array.
654
655CPP code:
656
657```cpp
658// Define OH_JSVM_GetAllPropertyNames.
659static JSVM_Value GetAllPropertyNames(JSVM_Env env, JSVM_CallbackInfo info)
660{
661    // Obtain the parameter passed from JS.
662    size_t argc = 1;
663    JSVM_Value args[1];
664    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
665    // Obtain names of all properties (own properties) of the specified object.
666    JSVM_Value result;
667    JSVM_Status status = OH_JSVM_GetAllPropertyNames(env, args[0],
668                                         JSVM_KeyCollectionMode::JSVM_KEY_OWN_ONLY,
669                                         JSVM_KeyFilter::JSVM_KEY_WRITABLE,
670                                         JSVM_KeyConversion::JSVM_KEY_NUMBERS_TO_STRINGS, &result);
671    if (status != JSVM_OK) {
672        OH_JSVM_ThrowError(env, nullptr, "Failed to get allpropertynames");
673        return nullptr;
674    } else {
675        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetAllPropertyNames success");
676    }
677    return result;
678}
679// Register the GetAllPropertyNames callback.
680static JSVM_CallbackStruct param[] = {
681    {.data = nullptr, .callback = GetAllPropertyNames},
682};
683static JSVM_CallbackStruct *method = param;
684// Set a property descriptor named getAllPropertyNames and associate it with a callback. This allows the GetAllPropertyNames callback to be called from JS.
685static JSVM_PropertyDescriptor descriptor[] = {
686    {"getAllPropertyNames", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
687};
688
689// Call the C++ code from JS.
690const char *srcCallNative = R"JS(
691    let obj = '{ data: 0, message: "hello world", 50: 1}';
692    let script = getAllPropertyNames(obj);
693)JS";
694```
695
696**Expected output**
697```ts
698JSVM OH_JSVM_GetAllPropertyNames success
699```
700