1# 使用Node-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++及ArkTS相关代码进行展示。 35 36### OH_JSVM_GetPropertyNames 37 38以字符串数组的形式获取对象的可枚举属性的名称,如果接口调用成功则返回JSVM_OK。 39 40cpp部分代码 41 42```cpp 43// GetPropertyNames注册回调 44static JSVM_CallbackStruct param[] = { 45 {.data = nullptr, .callback = GetPropertyNames}, 46}; 47static JSVM_CallbackStruct *method = param; 48// GetPropertyNames方法别名,供JS调用 49static JSVM_PropertyDescriptor descriptor[] = { 50 {"getPropertyNames", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 51}; 52// OH_JSVM_GetPropertyNames的样例方法 53static JSVM_Value GetPropertyNames(JSVM_Env env, JSVM_CallbackInfo info) 54{ 55 // 将obj作为参数传入 56 size_t argc = 1; 57 JSVM_Value args[1] = {nullptr}; 58 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 59 // 以字符串数组的形式获取对象的可枚举属性的名称,以result传出 60 JSVM_Value result = nullptr; 61 JSVM_Status status = OH_JSVM_GetPropertyNames(env, args[0], &result); 62 if (status != JSVM_OK) { 63 OH_JSVM_ThrowError(env, nullptr, "Failed to get propertynames"); 64 return nullptr; 65 } else { 66 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetPropertyNames success"); 67 } 68 return result; 69} 70``` 71 72ArkTS侧示例代码 73 74```ts 75import hilog from "@ohos.hilog" 76// 通过import的方式,引入Native能力。 77import napitest from "libentry.so" 78let obj = '{ data: 0, message: "hello world"}'; 79let script: string = `getPropertyNames(${obj})`; 80try { 81 let result = napitest.runJsVm(script); 82 hilog.info(0x0000, 'testJSVM', 'Test JSVM getPropertyNames: %{public}s', result); 83} catch (error) { 84 hilog.error(0x0000, 'testJSVM', 'Test JSVM getPropertyNames error: %{public}s', error.message); 85} 86``` 87 88### OH_JSVM_SetProperty 89 90将给定的属性与值设置入给定的Object 91 92cpp部分代码 93 94```cpp 95// SetProperty注册回调 96static JSVM_CallbackStruct param[] = { 97 {.data = nullptr, .callback = SetProperty}, 98}; 99static JSVM_CallbackStruct *method = param; 100// SetProperty方法别名,供JS调用 101static JSVM_PropertyDescriptor descriptor[] = { 102 {"setProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 103}; 104// OH_JSVM_SetProperty的样例方法 105static JSVM_Value SetProperty(JSVM_Env env, JSVM_CallbackInfo info) 106{ 107 // 接收js侧传入的三个参数:第一个参数为想要设置的object第二个参数为属性,第三个参数为属性对应的值 108 size_t argc = 3; 109 JSVM_Value args[3] = {nullptr}; 110 JSVM_Status status = OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 111 if (status != JSVM_OK) { 112 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_GetCbInfo fail"); 113 return nullptr; 114 } 115 // 通过调用OH_JSVM_SetProperty接口将属性与值设置入object如果失败,直接抛出错误 116 status = OH_JSVM_SetProperty(env, args[0], args[1], args[2]); 117 if (status != JSVM_OK) { 118 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_SetProperty fail"); 119 return nullptr; 120 } else { 121 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SetProperty success"); 122 } 123 // 将设置成功后的object返回出去 124 return args[0]; 125} 126``` 127 128ArkTS侧示例代码 129 130```ts 131import hilog from "@ohos.hilog" 132// 通过import的方式,引入Native能力。 133import napitest from "libentry.so" 134let script: string = ` 135 let obj = { data: 0, message: "hello world", 50: 1}; 136 setProperty(obj, "code", "hi") 137` 138try { 139 let result = napitest.runJsVm(script); 140 hilog.info(0x0000, 'testJSVM', 'Test JSVM setProperty: %{public}s', result); 141} catch (error) { 142 hilog.error(0x0000, 'testJSVM', 'Test JSVM setProperty error: %{public}s', error.message); 143} 144``` 145 146### OH_JSVM_GetProperty 147 148获取给定Object的给定属性对应的值 149 150cpp部分代码 151 152```cpp 153// GetProperty注册回调 154static JSVM_CallbackStruct param[] = { 155 {.data = nullptr, .callback = GetProperty}, 156}; 157static JSVM_CallbackStruct *method = param; 158// GetProperty方法别名,供JS调用 159static JSVM_PropertyDescriptor descriptor[] = { 160 {"getProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 161}; 162// OH_JSVM_GetProperty的样例方法 163static JSVM_Value GetProperty(JSVM_Env env, JSVM_CallbackInfo info) 164{ 165 // 接收两个js传来的参数 166 size_t argc = 2; 167 JSVM_Value args[2] = {nullptr}; 168 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 169 // 传入的第一个参数为要检测的object,第二个对象为要检测的属性,通过调用OH_JSVM_GetProperty接口获取对应的值 170 JSVM_Value result = nullptr; 171 JSVM_Status status = OH_JSVM_GetProperty(env, args[0], args[1], &result); 172 if (status != JSVM_OK) { 173 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_GetProperty fail"); 174 return nullptr; 175 } else { 176 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetProperty success"); 177 } 178 return result; 179} 180``` 181 182ArkTS侧示例代码 183 184```ts 185import hilog from "@ohos.hilog" 186// 通过import的方式,引入Native能力。 187import napitest from "libentry.so" 188let script: string = ` 189 let obj = { data: 0, message: "hello world", 50: 1}; 190 getProperty(obj, "message") 191` 192try { 193 let result = napitest.runJsVm(script); 194 hilog.info(0x0000, 'testJSVM', 'Test JSVM getProperty: %{public}s', result); 195} catch (error) { 196 hilog.error(0x0000, 'testJSVM', 'Test JSVM getProperty error: %{public}s', error.message); 197} 198``` 199 200### OH_JSVM_HasProperty 201 202检查对象中是否存在指定的属性,可以避免访问不存在属性导致的异常或错误 203 204cpp部分代码 205 206```cpp 207// HasProperty注册回调 208static JSVM_CallbackStruct param[] = { 209 {.data = nullptr, .callback = HasProperty}, 210}; 211static JSVM_CallbackStruct *method = param; 212// HasProperty方法别名,供JS调用 213static JSVM_PropertyDescriptor descriptor[] = { 214 {"hasProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 215}; 216// OH_JSVM_HasProperty的样例方法 217static JSVM_Value HasProperty(JSVM_Env env, JSVM_CallbackInfo info) 218{ 219 // 从js侧传入两个参数:第一个参数为要检验的对象,第二个参数为要检测是否存在对象的属性 220 size_t argc = 2; 221 JSVM_Value args[2] = {nullptr}; 222 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 223 // 将参数传入OH_JSVM_HasProperty方法中,若接口调用成功则将结果转化为JSVM_Value类型抛出,否则抛出错误 224 bool result; 225 JSVM_Status status = OH_JSVM_HasProperty(env, args[0], args[1], &result); 226 if (status != JSVM_OK) { 227 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_HasProperty fail"); 228 return nullptr; 229 } else { 230 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_HasProperty success:%{public}d", result); 231 } 232 // 若传入属性存在传入对象中,则输出true将结果转化为JSVM_Value类型抛出 233 JSVM_Value returnReslut = nullptr; 234 OH_JSVM_GetBoolean(env, result, &returnReslut); 235 return returnReslut; 236} 237``` 238 239ArkTS侧示例代码 240 241```ts 242import hilog from "@ohos.hilog" 243// 通过import的方式,引入Native能力。 244import napitest from "libentry.so" 245let script: string = ` 246 let obj = { data: 0, message: "hello world", 50: 1}; 247` 248let scriptTrue: string = script + `\n` + ` 249 hasProperty(obj, "data") 250` 251let scriptFalse: string = script + `\n` + ` 252 hasProperty(obj, 0) 253` 254try { 255 let resultTrue = napitest.runJsVm(scriptTrue); 256 hilog.info(0x0000, 'testJSVM', 'Test JSVM HasProperty: %{public}s', resultTrue); 257 let resultFalse = napitest.runJsVm(scriptFalse); 258 hilog.info(0x0000, 'testJSVM', 'Test JSVM HasProperty: %{public}s', resultFalse); 259} catch (error) { 260 hilog.error(0x0000, 'testJSVM', 'Test JSVM hasProperty error: %{public}s', error.message); 261} 262``` 263 264### OH_JSVM_DeleteProperty 265 266尝试从给定的Object中删除由key指定的属性,并返回操作的结果。 267如果对象是一个不可扩展的对象,或者属性是不可配置的,则可能无法删除该属性。 268 269cpp部分代码 270 271```cpp 272// DeleteProperty注册回调 273static JSVM_CallbackStruct param[] = { 274 {.data = nullptr, .callback = DeleteProperty}, 275}; 276static JSVM_CallbackStruct *method = param; 277// DeleteProperty方法别名,供JS调用 278static JSVM_PropertyDescriptor descriptor[] = { 279 {"deleteProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 280}; 281// OH_JSVM_DeleteProperty的样例方法 282static JSVM_Value DeleteProperty(JSVM_Env env, JSVM_CallbackInfo info) 283{ 284 // 获取js侧传入的两个参数 285 size_t argc = 2; 286 JSVM_Value args[2] = {nullptr}; 287 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 288 JSVM_ValueType valueType; 289 OH_JSVM_Typeof(env, args[0], &valueType); 290 if (valueType != JSVM_OBJECT) { 291 OH_JSVM_ThrowError(env, nullptr, "Expects an object as argument."); 292 return nullptr; 293 } 294 // 从传入的Object对象中删除指定属性,返回是否删除成功的bool结果值 295 bool result = false; 296 JSVM_Status status = OH_JSVM_DeleteProperty(env, args[0], args[1], &result); 297 if (status != JSVM_OK) { 298 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_DeleteProperty failed"); 299 return nullptr; 300 } else { 301 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_DeleteProperty success:%{public}d", result); 302 } 303 // 将bool结果转换为JSVM_value并返回 304 JSVM_Value ret; 305 OH_JSVM_GetBoolean(env, result, &ret); 306 return ret; 307} 308``` 309 310ArkTS侧示例代码 311 312```ts 313import hilog from "@ohos.hilog" 314// 通过import的方式,引入Native能力。 315import napitest from "libentry.so" 316let script: string = ` 317 let obj = { data: 0, message: "hello world", 50: 1}; 318 deleteProperty(obj, "message") 319` 320try { 321 let result = napitest.runJsVm(script); 322 hilog.info(0x0000, 'testJSVM', 'Test JSVM deleteProperty: %{public}s', result); 323} catch (error) { 324 hilog.error(0x0000, 'testJSVM', 'Test JSVM deleteProperty error: %{public}s', error.message); 325} 326``` 327 328### OH_JSVM_HasOwnProperty 329 330用于检查传入的Object是否具有自己的命名属性,不包括从原型链上继承的属性。 331 332cpp部分代码 333 334```cpp 335// HasOwnProperty注册回调 336static JSVM_CallbackStruct param[] = { 337 {.data = nullptr, .callback = HasOwnProperty}, 338}; 339static JSVM_CallbackStruct *method = param; 340// HasOwnProperty方法别名,供JS调用 341static JSVM_PropertyDescriptor descriptor[] = { 342 {"hasOwnProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 343}; 344// OH_JSVM_HasOwnProperty的样例方法 345static JSVM_Value HasOwnProperty(JSVM_Env env, JSVM_CallbackInfo info) 346{ 347 // 获取js侧传入的两个参数 348 size_t argc = 2; 349 JSVM_Value args[2] = {nullptr}; 350 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 351 // 检查第一个参数是否为对象 352 JSVM_ValueType valueType1; 353 OH_JSVM_Typeof(env, args[0], &valueType1); 354 if (valueType1 != JSVM_OBJECT) { 355 OH_JSVM_ThrowError(env, nullptr, "First argument must be an object."); 356 return nullptr; 357 } 358 // 检查第二个参数是否为string 359 JSVM_ValueType valuetype2; 360 OH_JSVM_Typeof(env, args[1], &valuetype2); 361 if (valuetype2 != JSVM_STRING ) { 362 OH_JSVM_ThrowError(env, nullptr, "Second argument must be a string."); 363 return nullptr; 364 } 365 // 检查对象是否具有指定属性,结果存储在hasProperty中 366 bool hasProperty; 367 JSVM_Status status = OH_JSVM_HasOwnProperty(env, args[0], args[1], &hasProperty); 368 if (status != JSVM_OK) { 369 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_HasOwnProperty failed"); 370 return nullptr; 371 } else { 372 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_HasOwnProperty success:%{public}d", hasProperty); 373 } 374 // 将bool结果转换为JSVM_Value并返回 375 JSVM_Value result; 376 OH_JSVM_GetBoolean(env, hasProperty, &result); 377 return result; 378} 379``` 380 381ArkTS侧示例代码 382 383```ts 384import hilog from "@ohos.hilog" 385// 通过import的方式,引入Native能力。 386import napitest from "libentry.so" 387let script: string = ` 388 let obj = { data: 0, message: "hello world", 50: 1}; 389` 390let scriptTrue: string = script + `\n` + ` 391 hasOwnProperty(obj, "message") 392` 393let scriptFalse: string = script + `\n` + ` 394 hasOwnProperty(obj, "__defineGetter__") 395` 396try { 397 let resultTrue = napitest.runJsVm(scriptTrue); 398 hilog.info(0x0000, 'testJSVM', 'Test JSVM hasOwnProperty: %{public}s', resultTrue); 399 let resultFalse = napitest.runJsVm(scriptFalse); 400 hilog.info(0x0000, 'testJSVM', 'Test JSVM hasOwnProperty: %{public}s', resultFalse); 401} catch (error) { 402 hilog.error(0x0000, 'testJSVM', 'Test JSVM hasOwnProperty error: %{public}s', error.message); 403} 404``` 405 406### OH_JSVM_SetNamedProperty 407 408用于在传入的Javascript对象上设置一个命名属性。 409 410cpp部分代码 411 412```cpp 413// SetNamedProperty注册回调 414static JSVM_CallbackStruct param[] = { 415 {.data = nullptr, .callback = SetNamedProperty}, 416}; 417static JSVM_CallbackStruct *method = param; 418// SetNamedProperty方法别名,供JS调用 419static JSVM_PropertyDescriptor descriptor[] = { 420 {"setNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 421}; 422// OH_JSVM_SetNamedProperty的样例方法 423static JSVM_Value SetNamedProperty(JSVM_Env env, JSVM_CallbackInfo info) 424{ 425 // 获取js侧传入的一个参数 426 size_t argc = 1; 427 JSVM_Value str; 428 char strKey[32] = ""; 429 OH_JSVM_GetCbInfo(env, info, &argc, &str, nullptr, nullptr); 430 // 获取传入参数字符串并存储在strKey中 431 size_t keyLength; 432 OH_JSVM_GetValueStringUtf8(env, str, strKey, 32, &keyLength); 433 // 创建一个新对象 434 JSVM_Value newObj; 435 OH_JSVM_CreateObject(env, &newObj); 436 // 设置整数值1234为属性值 437 int32_t value = 1234; 438 JSVM_Value numValue; 439 OH_JSVM_CreateInt32(env, value, &numValue); 440 // 将整数值与指定属性名关联 441 JSVM_Status status = OH_JSVM_SetNamedProperty(env, newObj, strKey, numValue); 442 if (status != JSVM_OK) { 443 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_SetNamedProperty failed"); 444 return nullptr; 445 } else { 446 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SetNamedProperty success"); 447 } 448 // 返回新创建并设置命名属性的对象 449 return newObj; 450} 451``` 452 453ArkTS侧示例代码 454 455```ts 456import hilog from "@ohos.hilog" 457// 通过import的方式,引入Native能力。 458import napitest from "libentry.so" 459let script: string = ` 460 setNamedProperty("message") 461` 462try { 463 let result = napitest.runJsVm(script); 464 hilog.info(0x0000, 'testJSVM', 'Test JSVM setNamedProperty: %{public}s', result); 465} catch (error) { 466 hilog.error(0x0000, 'testJSVM', 'Test JSVM setNamedProperty error: %{public}s', error.message); 467} 468``` 469 470### OH_JSVM_GetNamedProperty 471 472用于从Javascript对象中获取命名属性的值。 473 474cpp部分代码 475 476```cpp 477// GetNamedProperty注册回调 478static JSVM_CallbackStruct param[] = { 479 {.data = nullptr, .callback = GetNamedProperty}, 480}; 481static JSVM_CallbackStruct *method = param; 482// GetNamedProperty方法别名,供JS调用 483static JSVM_PropertyDescriptor descriptor[] = { 484 {"getNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 485}; 486// OH_JSVM_GetNamedProperty的样例方法 487static JSVM_Value GetNamedProperty(JSVM_Env env, JSVM_CallbackInfo info) 488{ 489 // 获取js侧传入的两个参数 490 size_t argc = 2; 491 JSVM_Value args[2] = {nullptr}; 492 char strKey[32] = ""; 493 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 494 // 获取要获取的属性名 495 size_t keyLength; 496 OH_JSVM_GetValueStringUtf8(env, args[1], strKey, 32, &keyLength); 497 // 获取指定属性的值并存储在result中 498 JSVM_Value result; 499 JSVM_Status status = OH_JSVM_GetNamedProperty(env, args[0], strKey, &result); 500 if (status != JSVM_OK) { 501 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_GetNamedProperty failed"); 502 return nullptr; 503 } else { 504 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNamedProperty success"); 505 } 506 return result; 507} 508``` 509 510ArkTS侧示例代码 511 512```ts 513import hilog from "@ohos.hilog" 514// 通过import的方式,引入Native能力。 515import napitest from "libentry.so" 516let script: string = ` 517 let obj = { data: 0, message: "hello world", 50: 1}; 518 getNamedProperty(obj, "message") 519` 520try { 521 let result = napitest.runJsVm(script); 522 hilog.info(0x0000, 'testJSVM', 'Test JSVM getNamedProperty: %{public}s', result); 523} catch (error) { 524 hilog.error(0x0000, 'testJSVM', 'Test JSVM getNamedProperty error: %{public}s', error.message); 525} 526``` 527 528### OH_JSVM_HasNamedProperty 529 530用于检查Javascript对象中是否包含指定的命名属性。 531 532cpp部分代码 533 534```cpp 535// HasNamedProperty注册回调 536static JSVM_CallbackStruct param[] = { 537 {.data = nullptr, .callback = HasNamedProperty}, 538}; 539static JSVM_CallbackStruct *method = param; 540// HasNamedProperty方法别名,供JS调用 541static JSVM_PropertyDescriptor descriptor[] = { 542 {"hasNamedProperty", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 543}; 544// OH_JSVM_HasNamedProperty的样例方法 545static JSVM_Value HasNamedProperty(JSVM_Env env, JSVM_CallbackInfo info) 546{ 547 // 获取js侧传入的两个参数 548 size_t argc = 2; 549 JSVM_Value args[2] = {nullptr}; 550 char strKey[32] = ""; 551 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 552 // 获取要检查的属性名 553 size_t keyLength; 554 OH_JSVM_GetValueStringUtf8(env, args[1], strKey, 32, &keyLength); 555 // 检查对象是否具有指定命名的属性,并将结果存储在hasProperty中 556 bool hasProperty = false; 557 JSVM_Status status = OH_JSVM_HasNamedProperty(env, args[0], strKey, &hasProperty); 558 if (status != JSVM_OK) { 559 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_HasNamedProperty failed"); 560 return nullptr; 561 } else { 562 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_HasNamedProperty success:%{public}d", hasProperty); 563 } 564 // 将bool结果转换为JSVM_Value并返回 565 JSVM_Value result; 566 OH_JSVM_GetBoolean(env, hasProperty, &result); 567 return result; 568} 569``` 570 571ArkTS侧示例代码 572 573```ts 574import hilog from "@ohos.hilog" 575// 通过import的方式,引入Native能力。 576import napitest from "libentry.so" 577let script: string = ` 578 let obj = { data: 0, message: "hello world", 50: 1}; 579 hasNamedProperty(obj, "message") 580` 581try { 582 let result = napitest.runJsVm(script); 583 hilog.info(0x0000, 'testJSVM', 'Test JSVM hasNamedProperty: %{public}s', result); 584} catch (error) { 585 hilog.error(0x0000, 'testJSVM', 'Test JSVM hasNamedProperty error: %{public}s', error.message); 586} 587``` 588 589### OH_JSVM_DefineProperties 590 591用于定义对象的自定义属性。 592 593cpp部分代码 594 595```cpp 596// DefineProperties注册回调 597static JSVM_CallbackStruct param[] = { 598 {.data = nullptr, .callback = DefineProperties}, 599}; 600static JSVM_CallbackStruct *method = param; 601// DefineProperties方法别名,供JS调用 602static JSVM_PropertyDescriptor descriptor[] = { 603 {"defineProperties", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 604}; 605// OH_JSVM_DefineProperties的样例方法 606static JSVM_Value DefineMethodPropertiesExample(JSVM_Env env, JSVM_CallbackInfo info) 607{ 608 int32_t propValue = 26; 609 JSVM_Value returnValue; 610 OH_JSVM_CreateInt32(env, propValue, &returnValue); 611 return returnValue; 612} 613 614// Getter回调函数 615static JSVM_Value GetterCallback(JSVM_Env env, JSVM_CallbackInfo info) 616{ 617 JSVM_Value result; 618 const char *str = "Hello world!"; 619 size_t length = strlen(str); 620 // 创建属性的值 621 OH_JSVM_CreateStringUtf8(env, str, length, &result); 622 return result; 623} 624 625static JSVM_Value RunScriptAndLogResult(JSVM_Env env, const std::string &srcCode) { 626 JSVM_Value sourceCodeValue; 627 OH_JSVM_CreateStringUtf8(env, srcCode.c_str(), srcCode.size(), &sourceCodeValue); 628 JSVM_Script script; 629 // 编译JavaScript代码字符串并返回编译后的脚本 630 OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script); 631 JSVM_Value jsVmResult; 632 // 执行JavaScript代码字符串 633 OH_JSVM_RunScript(env, script, &jsVmResult); 634 return jsVmResult; 635} 636 637static JSVM_Value DefineProperties(JSVM_Env env, JSVM_CallbackInfo info) { 638 // 接受一个JavaScript侧传入的空object 639 size_t argc = 2; 640 JSVM_Value argv[2] = {nullptr}; 641 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 642 // 创建一个string类型的属性值 643 size_t length = 0; 644 OH_JSVM_GetValueStringUtf8(env, argv[1], nullptr, 0, &length); 645 char *buf = (char *)malloc(length + 1); 646 OH_JSVM_GetValueStringUtf8(env, argv[1], buf, length + 1, &length); 647 JSVM_Value stringValue; 648 OH_JSVM_CreateStringUtf8(env, "Hello!", JSVM_AUTO_LENGTH, &stringValue); 649 JSVM_CallbackStruct param[] = { 650 {.data = nullptr, .callback = DefineMethodPropertiesExample}, 651 {.data = nullptr, .callback = GetterCallback}, 652 653 }; 654 JSVM_PropertyDescriptor descriptor[] = { 655 // 定义method类型的属性值 656 {"defineMethodPropertiesExample", nullptr, ¶m[0], nullptr, nullptr, nullptr, JSVM_DEFAULT}, 657 // 定义string类型的属性值 658 {"defineStringPropertiesExample", nullptr, nullptr, nullptr, nullptr, stringValue, JSVM_DEFAULT}, 659 // 定义getter类型的属性值 660 {"getterCallback", nullptr, nullptr, ¶m[1], nullptr, nullptr,JSVM_DEFAULT}}; 661 // 创建一个method类型的属性值 662 // 在obj对象上定义了一个函数defineMethodPropertiesExample,在函数defineMethodPropertiesExample中定义了一个变量并返回, 663 // 在调用obj的这个对象时可以调用这个函数 664 static std::string srcMethod; 665 JSVM_Status statusMethod; 666 statusMethod = OH_JSVM_DefineProperties(env, *argv, sizeof(descriptor) / sizeof(descriptor[0]), descriptor); 667 // 运行obj.defineMethodPropertiesExample()并将结果返回给JavaScript 668 srcMethod = R"JS(obj.defineMethodPropertiesExample();)JS"; 669 JSVM_Value jsVmResult = RunScriptAndLogResult(env, srcMethod); 670 // 创建string类型的属性值 671 static std::string srcString; 672 JSVM_Status statusString; 673 statusString = OH_JSVM_DefineProperties(env, *argv, sizeof(descriptor) / sizeof(descriptor[1]), descriptor); 674 // 运行obj.defineStringPropertiesExample()并将结果返回给JavaScript 675 srcString = R"JS(obj.defineStringPropertiesExample;)JS"; 676 JSVM_Value jsVmResult1 = RunScriptAndLogResult(env, srcString); 677 // 定义带有getter的属性 678 static std::string srcGetter; 679 JSVM_Status statusGetter; 680 statusGetter = OH_JSVM_DefineProperties(env, *argv, sizeof(descriptor) / sizeof(descriptor[2]), descriptor); 681 // 调用obj的getterCallback()并将结果字符串返回给JavaScript 682 srcGetter = R"JS(obj.getterCallback;)JS"; 683 JSVM_Value jsVmResult2 = RunScriptAndLogResult(env, srcGetter); 684 if (statusMethod != JSVM_OK || statusString != JSVM_OK || statusGetter != JSVM_OK) { 685 OH_JSVM_ThrowError(env, nullptr, "JSVM DefineProperties fail"); 686 return nullptr; 687 } else if (statusMethod == JSVM_OK) { 688 int32_t number; 689 OH_JSVM_GetValueInt32(env, jsVmResult, &number); 690 OH_LOG_INFO(LOG_APP, "JSVM DefineMethodPropertiesExample success:%{public}d", number); 691 } else if (statusString == JSVM_OK) { 692 size_t length = 0; 693 OH_JSVM_GetValueStringUtf8(env, jsVmResult1, nullptr, 0, &length); 694 char *buf = (char *)malloc(length + 1); 695 OH_JSVM_GetValueStringUtf8(env, jsVmResult1, buf, length + 1, &length); 696 OH_LOG_INFO(LOG_APP, "JSVM defineStringPropertiesExample success:%{public}s", buf); 697 } else if (statusGetter == JSVM_OK) { 698 size_t length = 0; 699 OH_JSVM_GetValueStringUtf8(env, jsVmResult2, nullptr, 0, &length); 700 char *buf = (char *)malloc(length + 1); 701 OH_JSVM_GetValueStringUtf8(env, jsVmResult2, buf, length + 1, &length); 702 OH_LOG_INFO(LOG_APP, "JSVM getterCallback success:%{public}s", buf); 703 } 704 return jsVmResult; 705} 706``` 707 708ArkTS侧示例代码 709 710```ts 711import hilog from "@ohos.hilog" 712// 通过import的方式,引入Native能力。 713import napitest from "libentry.so" 714// 定义method类型的属性 715let script: string = ` 716 let obj = {}; 717 defineProperties(obj) 718` 719let result = napitest.runJsVm(script); 720hilog.info(0x0000, 'testJSVM', 'Test JSVM defineGetterProperties: %{public}s', result); 721``` 722 723### OH_JSVM_GetAllPropertyNames 724 725获取给定对象的所有可用属性名称, 结果变量将存储一个包含所有可枚举属性名称的JavaScript数组。 726 727cpp部分代码 728 729```cpp 730// GetAllPropertyNames注册回调 731static JSVM_CallbackStruct param[] = { 732 {.data = nullptr, .callback = GetAllPropertyNames}, 733}; 734static JSVM_CallbackStruct *method = param; 735// GetAllPropertyNames方法别名,供JS调用 736static JSVM_PropertyDescriptor descriptor[] = { 737 {"getAllPropertyNames", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 738}; 739// OH_JSVM_GetAllPropertyNames的样例方法 740static JSVM_Value GetAllPropertyNames(JSVM_Env env, JSVM_CallbackInfo info) 741{ 742 // // 获取js侧传入的一个参数 743 size_t argc = 1; 744 JSVM_Value args[1]; 745 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 746 // 获取给定对象的所有属性名称(自有属性) 747 JSVM_Value result; 748 JSVM_Status status = OH_JSVM_GetAllPropertyNames(env, args[0], 749 JSVM_KeyCollectionMode::JSVM_KEY_OWN_ONLY, 750 JSVM_KeyFilter::JSVM_KEY_WRITABLE, 751 JSVM_KeyConversion::JSVM_KEY_NUMBERS_TO_STRINGS, &result); 752 if (status != JSVM_OK) { 753 OH_JSVM_ThrowError(env, nullptr, "Failed to get allpropertynames"); 754 return nullptr; 755 } else { 756 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetAllPropertyNames success"); 757 } 758 return result; 759} 760``` 761 762ArkTS侧示例代码 763 764```ts 765import hilog from "@ohos.hilog" 766// 通过import的方式,引入Native能力。 767import napitest from "libentry.so" 768let obj = '{ data: 0, message: "hello world", 50: 1}'; 769let script: string = ` 770 getAllPropertyNames(${obj}) 771 ` 772try { 773 let result = napitest.runJsVm(script); 774 hilog.info(0x0000, 'testJSVM', 'Test JSVM GetAllPropertyNames: %{public}s', result); 775} catch (error) { 776 hilog.error(0x0000, 'testJSVM', 'Test JSVM GetAllPropertyNames error: %{public}s', error.message); 777} 778``` 779