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, ¶m[0], nullptr, nullptr, nullptr, JSVM_DEFAULT}, 581 // 定义string类型的属性值 582 {"defineStringPropertiesExample", nullptr, nullptr, nullptr, nullptr, stringValue, JSVM_DEFAULT}, 583 // 定义getter类型的属性值 584 {"getterCallback", nullptr, nullptr, ¶m[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