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, ¶m[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, ¶m[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