• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用JSVM-API接口进行object相关开发
2
3## 简介
4
5使用JSVM-API接口进行object相关开发,处理JavaScript对象的基本操作的功能,例如创建对象、获取原型、冻结和密封对象,检查对象的类型等。这些操作是在处理JavaScript对象时非常常见的,提供了一种与JavaScript对象交互的方式。
6
7## 基本概念
8
9在JSVM接口开发中,经常需要定义和操作对象。例如,创建一个API接口,该接口接受一个对象作为输入参数,对该对象执行某些操作,并返回一个结果对象。在这个过程中,需要确保接口的定义清晰、规范,并且与对象的属性和方法相兼容。
10
11- **接口(API)**:接口定义了组件之间的交互协议,包括输入参数、输出结果以及可能的错误处理。通过接口,组件可以相互调用和交换数据,而无需了解对方的内部实现细节。
12- **对象(Object)**:在JavaScript,对象是一种复合数据类型,允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值,而方法则是对象可以执行的操作。
13
14## 接口说明
15
16| 接口                       | 功能说明                                     |
17| -------------------------- | -------------------------------------------- |
18| OH_JSVM_GetPrototype         | 获取给定JavaScript对象的原型。             |
19| OH_JSVM_CreateObject         | 创建一个默认的JavaScript Object对象。                   |
20| OH_JSVM_ObjectFreeze         | 冻结给定的对象,防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。                             |
21| OH_JSVM_ObjectSeal           |  密封给定的对象。这可以防止向其添加新属性,以及将所有现有属性标记为不可配置。                             |
22| OH_JSVM_Typeof                | 返回JavaScript对象的类型。  |
23| OH_JSVM_Instanceof            | 判断一个对象是否是某个构造函数的实例。    |
24| OH_JSVM_TypeTagObject       | 将type_tag指针的值与JavaScript对象或外部对象相关联。                  |
25| OH_JSVM_CheckObjectTypeTag | 检查给定的类型标签是否与对象上的类型标签匹配。 |
26| OH_JSVM_CreateSymbol         | 根据给定的描述符创建一个Symbol对象。                     |
27|OH_JSVM_SymbolFor | 在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新Symbol |
28| OH_JSVM_CreateExternal       | 创建一个包装了外部指针的JavaScript对象               |
29| OH_JSVM_GetValueExternal    | 获取先前传递给OH_JSVM_CreateExternal的外部数据指针                  |
30
31## 使用示例
32
33JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
34
35### OH_JSVM_GetPrototype
36
37获取给定JavaScript对象的原型。
38
39cpp部分代码
40
41```cpp
42// hello.cpp
43#include "napi/native_api.h"
44#include "ark_runtime/jsvm.h"
45#include <hilog/log.h>
46// GetPrototype注册回调
47static JSVM_CallbackStruct param[] = {
48    {.data = nullptr, .callback = GetPrototype},
49};
50static JSVM_CallbackStruct *method = param;
51// GetPrototype方法别名,供JS调用
52static JSVM_PropertyDescriptor descriptor[] = {
53    {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
54};
55// OH_JSVM_GetPrototype的样例方法
56static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info)
57{
58    // 创建一个空对象
59    JSVM_Value obj = nullptr;
60    OH_JSVM_CreateObject(env, &obj);
61    const char *testNameStr = "set and get proto";
62    JSVM_Value propValue = nullptr;
63    JSVM_Value key = nullptr;
64    OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &key);
65    OH_JSVM_CreateStringUtf8(env, testNameStr, strlen(testNameStr), &propValue);
66    OH_JSVM_SetProperty(env, obj, key, propValue);
67    // 获取属性
68    JSVM_Value propResult = nullptr;
69    JSVM_Status status = OH_JSVM_GetProperty(env, obj, key, &propResult);
70    if (status != JSVM_OK) {
71        OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail");
72    } else {
73        OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success");
74    }
75    return propResult;
76}
77```
78
79ArkTS侧示例代码
80
81```ts
82import hilog from "@ohos.hilog"
83// 通过import的方式,引入Native能力。
84import napitest from "libentry.so"
85let script: string = `getPrototype()`;
86try {
87  let result = napitest.runJsVm(script);
88  hilog.info(0x0000, 'testJSVM', 'Test JSVM getPrototype: %{public}s', result);
89} catch (error) {
90  hilog.error(0x0000, 'testJSVM', 'Test JSVM getPrototype error: %{public}s', error.message);
91}
92```
93
94### OH_JSVM_CreateObject
95
96创建一个默认的JavaScript Object对象。
97
98cpp部分代码
99
100```cpp
101// hello.cpp
102#include "napi/native_api.h"
103#include "ark_runtime/jsvm.h"
104#include <hilog/log.h>
105// CreateObject注册回调
106static JSVM_CallbackStruct param[] = {
107    {.data = nullptr, .callback = CreateObject},
108};
109static JSVM_CallbackStruct *method = param;
110// CreateObject方法别名,供JS调用
111static JSVM_PropertyDescriptor descriptor[] = {
112    {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
113};
114// OH_JSVM_CreateObject的样例方法
115static JSVM_Value CreateObject(JSVM_Env env, JSVM_CallbackInfo info)
116{
117    JSVM_Value object = nullptr;
118    // 创建一个空对象
119    JSVM_Status status = OH_JSVM_CreateObject(env, &object);
120    if (status != JSVM_OK) {
121        OH_LOG_ERROR(LOG_APP, "JSVM CreateObject fail");
122    } else {
123        OH_LOG_INFO(LOG_APP, "JSVM CreateObject success");
124    }
125    // 设置对象的属性
126    JSVM_Value name = nullptr;
127    // 设置属性名为 "name"
128    OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &name);
129    JSVM_Value value = nullptr;
130    // 设置属性值为 "Hello from N-API!"
131    OH_JSVM_CreateStringUtf8(env, "Hello OH_JSVM_CreateObject!", JSVM_AUTO_LENGTH, &value);
132    // 将属性设置到对象上
133    OH_JSVM_SetProperty(env, object, name, value);
134    return object;
135}
136```
137
138ArkTS侧示例代码
139
140```ts
141import hilog from "@ohos.hilog"
142// 通过import的方式,引入Native能力。
143import napitest from "libentry.so"
144let script: string = `createObject()`;
145try {
146  let result = napitest.runJsVm(script);
147  hilog.info(0x0000, 'testJSVM', 'Test JSVM createObject: %{public}s', result);
148} catch (error) {
149  hilog.error(0x0000, 'testJSVM', 'Test JSVM createObject error: %{public}s', error.message);
150}
151```
152
153### OH_JSVM_ObjectFreeze
154
155冻结给定的对象,防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。
156
157cpp部分代码
158
159```cpp
160// hello.cpp
161#include "napi/native_api.h"
162#include "ark_runtime/jsvm.h"
163#include <hilog/log.h>
164// ObjectFreeze注册回调
165static JSVM_CallbackStruct param[] = {
166    {.data = nullptr, .callback = ObjectFreeze},
167};
168static JSVM_CallbackStruct *method = param;
169// ObjectFreeze方法别名,供JS调用
170static JSVM_PropertyDescriptor descriptor[] = {
171    {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
172};
173// OH_JSVM_ObjectFreeze的样例方法
174static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info)
175{
176    // 接受一个JavaScript侧传入的object
177    size_t argc = 1;
178    JSVM_Value argv[1] = {nullptr};
179    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
180    // 调用接口OH_JSVM_ObjectFreeze将传入的object冻结
181    JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]);
182    if (status == JSVM_OK) {
183        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success");
184    }
185    // 测试冻结后的对象中属性能否修改
186    JSVM_Value value = nullptr;
187    OH_JSVM_CreateInt32(env, 111111, &value);
188    OH_JSVM_SetNamedProperty(env, argv[0], "data", value);
189    // 将冻结后修改过的属性返回JavaScript侧
190    return argv[0];
191}
192```
193
194ArkTS侧示例代码
195
196```ts
197import hilog from "@ohos.hilog"
198// 通过import的方式,引入Native能力。
199import napitest from "libentry.so"
200let script: string = `
201  let obj = { data: 55, message: "hello world"};
202  objectFreeze(obj)
203`
204try {
205  let result = napitest.runJsVm(script);
206  // 冻结后的对象还是之前的属性值并未修改
207  hilog.info(0x0000, 'testJSVM', 'Test JSVM objectFreeze: %{public}s', result);
208} catch (error) {
209  hilog.error(0x0000, 'testJSVM', 'Test JSVM objectFreeze error: %{public}s', error.message);
210}
211```
212
213### OH_JSVM_ObjectSeal
214
215密封给定的对象。这可以防止向其添加新属性,以及将所有现有属性标记为不可配置。
216
217cpp部分代码
218
219```cpp
220// hello.cpp
221#include "napi/native_api.h"
222#include "ark_runtime/jsvm.h"
223#include <hilog/log.h>
224// ObjectSeal注册回调
225static JSVM_CallbackStruct param[] = {
226    {.data = nullptr, .callback = ObjectSeal},
227};
228static JSVM_CallbackStruct *method = param;
229// ObjectSeal方法别名,供JS调用
230static JSVM_PropertyDescriptor descriptor[] = {
231    {"objectSeal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
232};
233// OH_JSVM_ObjectSeal的样例方法
234static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info)
235{
236    // 接受一个JavaScript侧传入的object
237    size_t argc = 1;
238    JSVM_Value argv[1] = {nullptr};
239    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
240    // 调用接口OH_JSVM_ObjectSeal将传入的object封闭,使其无法添加新的属性
241    JSVM_Status status = OH_JSVM_ObjectSeal(env, argv[0]);
242    if (status == JSVM_OK) {
243        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal success");
244    }
245    // 检查封闭后的对象中属性能否修改、删除、新增
246    // 封闭后对象修改
247    JSVM_Value changeValue = nullptr;
248    OH_JSVM_CreateInt32(env, 111111, &changeValue);
249    OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue);
250    // 封闭后对象删除
251    JSVM_Value deleteProperty = nullptr;
252    OH_JSVM_CreateStringUtf8(env, "message", JSVM_AUTO_LENGTH, &deleteProperty);
253    bool result = false;
254    OH_JSVM_DeleteProperty(env, argv[0], deleteProperty, &result);
255    if (result) {
256        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed");
257    }
258    // 封闭后对象新增
259    JSVM_Value addValue = nullptr;
260    OH_JSVM_CreateStringUtf8(env, "addValue", JSVM_AUTO_LENGTH, &addValue);
261    OH_JSVM_SetNamedProperty(env, argv[0], "newProperty", addValue);
262    // 将封闭后改动过的对象返回JavaScript侧
263    return argv[0];
264}
265```
266
267ArkTS侧示例代码
268
269```ts
270import hilog from "@ohos.hilog"
271// 通过import的方式,引入Native能力。
272import napitest from "libentry.so"
273let script: string = `
274  let obj = { data: 55, message: "hello world"};
275  objectSeal(obj)
276`
277try {
278  let result = napitest.runJsVm(script);
279  // 封闭后的对象输出后显示可以修改但不能删除和新增
280  hilog.info(0x0000, 'testJSVM', 'Test JSVM objectSeal: %{public}s', result);
281} catch (error) {
282  hilog.error(0x0000, 'testJSVM', 'Test JSVM objectSeal error: %{public}s', error.message);
283}
284```
285
286### OH_JSVM_Typeof
287
288返回JavaScript对象的类型。
289
290cpp部分代码
291
292```cpp
293// hello.cpp
294#include "napi/native_api.h"
295#include "ark_runtime/jsvm.h"
296#include <hilog/log.h>
297// GetTypeof注册回调
298static JSVM_CallbackStruct param[] = {
299    {.data = nullptr, .callback = GetTypeof},
300};
301static JSVM_CallbackStruct *method = param;
302// GetTypeof方法别名,TS侧调用
303static JSVM_PropertyDescriptor descriptor[] = {
304    {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
305};
306// OH_JSVM_Typeof的样例方法
307static JSVM_Value GetTypeof(JSVM_Env env, JSVM_CallbackInfo info) {
308    size_t argc = 1;
309    JSVM_Value args[1] = {nullptr};
310    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
311    JSVM_ValueType valueType;
312    OH_JSVM_Typeof(env, args[0], &valueType);
313    JSVM_Value type = nullptr;
314    switch (valueType) {
315    case JSVM_UNDEFINED:
316        OH_LOG_INFO(LOG_APP, "JSVM Input type is undefined");
317        OH_JSVM_CreateStringUtf8(env, "Input type is undefined", JSVM_AUTO_LENGTH, &type);
318        break;
319    case JSVM_NULL:
320        OH_LOG_INFO(LOG_APP, "JSVM Input type is null");
321        OH_JSVM_CreateStringUtf8(env, "Input type is null", JSVM_AUTO_LENGTH, &type);
322        break;
323    case JSVM_BOOLEAN:
324        OH_LOG_INFO(LOG_APP, "JSVM Input type is boolean");
325        OH_JSVM_CreateStringUtf8(env, "Input type is boolean", JSVM_AUTO_LENGTH, &type);
326        break;
327    case JSVM_NUMBER:
328        OH_LOG_INFO(LOG_APP, "JSVM Input type is number");
329        OH_JSVM_CreateStringUtf8(env, "Input type is number", JSVM_AUTO_LENGTH, &type);
330        break;
331    case JSVM_STRING:
332        OH_LOG_INFO(LOG_APP, "JSVM Input type is string");
333        OH_JSVM_CreateStringUtf8(env, "Input type is string", JSVM_AUTO_LENGTH, &type);
334        break;
335    case JSVM_SYMBOL:
336        OH_LOG_INFO(LOG_APP, "JSVM Input type is symbol");
337        OH_JSVM_CreateStringUtf8(env, "Input type is symbol", JSVM_AUTO_LENGTH, &type);
338        break;
339    case JSVM_OBJECT:
340        OH_LOG_INFO(LOG_APP, "JSVM Input type is object");
341        OH_JSVM_CreateStringUtf8(env, "Input type is object", JSVM_AUTO_LENGTH, &type);
342        break;
343    case JSVM_FUNCTION:
344        OH_LOG_INFO(LOG_APP, "JSVM Input type is function");
345        OH_JSVM_CreateStringUtf8(env, "Input type is function", JSVM_AUTO_LENGTH, &type);
346        break;
347    case JSVM_EXTERNAL:
348        OH_LOG_INFO(LOG_APP, "JSVM Input type is external");
349        OH_JSVM_CreateStringUtf8(env, "Input type is external", JSVM_AUTO_LENGTH, &type);
350        break;
351    case JSVM_BIGINT:
352        OH_LOG_INFO(LOG_APP, "JSVM Input type is bigint");
353        OH_JSVM_CreateStringUtf8(env, "Input type is bigint", JSVM_AUTO_LENGTH, &type);
354        break;
355    default:
356        OH_LOG_INFO(LOG_APP, "JSVM Input type does not match any");
357        OH_JSVM_CreateStringUtf8(env, " ", JSVM_AUTO_LENGTH, &type);
358        break;
359    }
360    return type;
361}
362```
363
364ArkTS侧示例代码
365
366```ts
367import hilog from "@ohos.hilog"
368// 通过import的方式,引入Native能力。
369import napitest from "libentry.so"
370let script: string = `
371getTypeof(true);
372  `;
373try {
374  let result = napitest.runJsVm(script);
375  hilog.info(0x0000, 'JSVM', 'GetTypeof: %{public}s', result);
376} catch (error) {
377  hilog.error(0x0000, 'JSVM', 'GetTypeof: %{public}s', error.message);
378}
379```
380
381### OH_JSVM_Instanceof
382
383判断一个对象是否是某个构造函数的实例。
384
385cpp部分代码
386
387```cpp
388// hello.cpp
389#include "napi/native_api.h"
390#include "ark_runtime/jsvm.h"
391#include <hilog/log.h>
392// InstanceOf注册回调
393static JSVM_CallbackStruct param[] = {
394    {.data = nullptr, .callback = InstanceOf},
395};
396static JSVM_CallbackStruct *method = param;
397// InstanceOf方法别名,TS侧调用
398static JSVM_PropertyDescriptor descriptor[] = {
399    {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
400};
401// OH_JSVM_Instanceof的样例方法
402static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info)
403{
404    // 获取两个JavaScript侧传入的参数
405    size_t argc = 2;
406    JSVM_Value args[2] = {nullptr};
407    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
408    bool result = false;
409    JSVM_Status status = OH_JSVM_Instanceof(env, args[0], args[1], &result);
410    if (status != JSVM_OK) {
411        OH_LOG_ERROR(LOG_APP, "JSVM InstanceOf fail");
412    } else {
413        OH_LOG_INFO(LOG_APP, "JSVM InstanceOf:%{public}d", result);
414    }
415    JSVM_Value returnValue = nullptr;
416    OH_JSVM_GetBoolean(env, result, &returnValue);
417    return returnValue;
418}
419```
420
421ArkTS侧示例代码
422
423```ts
424import hilog from "@ohos.hilog"
425// 通过import的方式,引入Native能力。
426import napitest from "libentry.so"
427let script: string = `
428      class Person {
429        name;
430        age;
431        constructor(name, age) {
432          this.name = name;
433          this.age = age;
434        }
435      }
436     instanceOf(new Person('Alice', 30), Person);
437     ;
438        `;
439try {
440  let result = napitest.runJsVm(script.toString());
441  hilog.info(0x0000, 'JSVM', 'InstanceOf: %{public}s', result);
442} catch (error) {
443  hilog.error(0x0000, 'JSVM', 'InstanceOf: %{public}s', error.message);
444}
445```
446
447### OH_JSVM_TypeTagObject
448
449使用类型标签type_tag来标记JavaScript对象,后续可以更精确地识别JavaScript对象。
450
451### OH_JSVM_CheckObjectTypeTag
452
453检查给定的类型标签是否与对象上的类型标签匹配。
454
455cpp部分代码
456
457```cpp
458// hello.cpp
459#include "napi/native_api.h"
460#include "ark_runtime/jsvm.h"
461#include <hilog/log.h>
462// SetTypeTagToObject,CheckObjectTypeTag注册回调
463static JSVM_CallbackStruct param[] = {
464    {.data = nullptr, .callback = SetTypeTagToObject},
465    {.data = nullptr, .callback = CheckObjectTypeTag},
466};
467static JSVM_CallbackStruct *method = param;
468// SetTypeTagToObject,CheckObjectTypeTag方法别名,TS侧调用
469static JSVM_PropertyDescriptor descriptor[] = {
470    {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
471    {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
472};
473#define NUMBERINT_FOUR 4
474// 定义一个静态常量JSVM_TypeTag数组存储类型标签
475static const JSVM_TypeTag TagsData[NUMBERINT_FOUR] = {
476    {0x9e4b2449547061b3, 0x33999f8a6516c499},
477    {0x1d55a794c53a726d, 0x43633f509f9c944e},
478    {0, 0}, // 用于表示无标签或默认标签
479    {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0},
480};
481// OH_JSVM_TypeTagObject的样例方法
482static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info)
483{
484    // 获取两个JavaScript侧传入的参数
485    size_t argc = 2;
486    JSVM_Value args[2] = {nullptr};
487    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
488    // 获取索引数字转换为JSVM_Value
489    int32_t index = 0;
490    OH_JSVM_GetValueInt32(env, args[1], &index);
491    // 给参数(对象)设置类型标签
492    JSVM_Status status = OH_JSVM_TypeTagObject(env, args[0], &TagsData[index]);
493    if (status != JSVM_OK) {
494        OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail");
495    } else {
496        OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success");
497    }
498    // 将bool结果转换为JSVM_Value并返回
499    JSVM_Value result = nullptr;
500    OH_JSVM_GetBoolean(env, true, &result);
501    return result;
502}
503// OH_JSVM_CheckObjectTypeTag的样例方法
504static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info)
505{
506    // 获取两个JavaScript侧传入的参数
507    size_t argc = 2;
508    JSVM_Value args[2] = {nullptr};
509    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
510    // 获取索引数字转换为JSVM_Value
511    int32_t index = 0;
512    OH_JSVM_GetValueInt32(env, args[1], &index);
513    // 检查对象的类型标签
514    bool checkResult = false;
515    JSVM_Status status = OH_JSVM_CheckObjectTypeTag(env, args[0], &TagsData[index], &checkResult);
516    if (status != JSVM_OK) {
517        OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail");
518    } else {
519        OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject:%{public}d", checkResult);
520    }
521    // 将bool结果转换为JSVM_Value并返回
522    JSVM_Value checked = nullptr;
523    OH_JSVM_GetBoolean(env, checkResult, &checked);
524    return checked;
525}
526```
527
528ArkTS侧示例代码
529
530```ts
531import hilog from "@ohos.hilog"
532// 通过import的方式,引入Native能力。
533import napitest from "libentry.so"
534let script: string = `
535         class Obj {
536           data;
537           message;
538         }
539         let obj= { data: 0, message: "hello world"};
540         setTypeTagToObject(obj, 0)
541       `
542try {
543  let result = napitest.runJsVm(script);
544  hilog.info(0x0000, 'JSVM', 'SetTypeTagToObject: %{public}s', result);
545} catch (error) {
546  hilog.error(0x0000, 'JSVM', 'SetTypeTagToObject: %{public}s', error.message);
547}
548let script: string = `
549         class Obj {
550           data;
551           message;
552         }
553         let obj= { data: 0, message: "hello world"};
554         setTypeTagToObject(obj,0)
555         checkObjectTypeTag(obj,0);
556       `
557try {
558  let result = napitest.runJsVm(script);
559  hilog.info(0x0000, 'JSVM', 'CheckObjectTypeTag: %{public}s', result);
560} catch (error) {
561  hilog.error(0x0000, 'JSVM', 'CheckObjectTypeTag: %{public}s', error.message);
562}
563```
564
565### OH_JSVM_CreateExternal
566
567创建一个包装了外部指针的JavaScript对象
568
569cpp部分代码
570
571```cpp
572// hello.cpp
573#include "napi/native_api.h"
574#include "ark_runtime/jsvm.h"
575#include <hilog/log.h>
576// CreateExternal注册回调
577static JSVM_CallbackStruct param[] = {
578    {.data = nullptr, .callback = CreateExternal},
579};
580static JSVM_CallbackStruct *method = param;
581// CreateExternal方法别名,供JS调用
582static JSVM_PropertyDescriptor descriptor[] = {
583    {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
584};
585// OH_JSVM_CreateExternal的样例方法
586static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info)
587{
588    size_t dataSize = 10;
589    void *data = malloc(dataSize);
590    memset(data, 0, dataSize);
591    const char testStr[] = "test";
592    JSVM_Value external = nullptr;
593    JSVM_Status status = OH_JSVM_CreateExternal(
594        env, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, (void *)testStr, &external);
595    JSVM_Value returnValue = nullptr;
596    bool type = false;
597    if (status != JSVM_OK) {
598        OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status);
599        return nullptr;
600    } else {
601        type = true;
602        OH_LOG_INFO(LOG_APP, "JSVM CreateExternal:%{public}d", type);
603    }
604    OH_JSVM_GetBoolean(env, type, &returnValue);
605    // 返回结果
606    return returnValue;
607}
608```
609
610ArkTS侧示例代码
611
612```ts
613import hilog from "@ohos.hilog"
614// 通过import的方式,引入Native能力。
615import napitest from "libentry.so"
616let script: string = `createExternal()`;
617try {
618  let result = napitest.runJsVm(script);
619  hilog.info(0x0000, 'testJSVM', 'Test JSVM createExternal: %{public}s', result);
620} catch (error) {
621  hilog.error(0x0000, 'testJSVM', 'Test JSVM createExternal error: %{public}s', error.message);
622}
623```
624
625### OH_JSVM_GetValueExternal
626
627OH_JSVM_CreateExternal可以创建包装自定义的C/C++对象并将其公开给JavaScript代码,而OH_JSVM_GetValueExternal就是用来获得OH_JSVM_CreateExternal所创建的外部对象的。
628
629cpp部分代码
630
631```cpp
632// hello.cpp
633#include "napi/native_api.h"
634#include "ark_runtime/jsvm.h"
635#include <hilog/log.h>
636// GetValueExternal注册回调
637static JSVM_CallbackStruct param[] = {
638    {.data = nullptr, .callback = GetValueExternal},
639};
640static JSVM_CallbackStruct *method = param;
641// GetValueExternal方法别名,供JS调用
642static JSVM_PropertyDescriptor descriptor[] = {
643    {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
644};
645// OH_JSVM_GetValueExternal的样例方法
646static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info)
647{
648    void *data = (void *)0x12345;
649    JSVM_Value externalValue = nullptr;
650    JSVM_Status status = OH_JSVM_CreateExternal(env, data, nullptr, nullptr, &externalValue);
651    if (status != JSVM_OK) {
652        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail");
653    }
654    void *data_value;
655    status = OH_JSVM_GetValueExternal(env, externalValue, &data_value);
656    bool type = false;
657    if (status != JSVM_OK) {
658        OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail");
659    }
660    type = true;
661    OH_LOG_INFO(LOG_APP, "JSVM API Get ValueExternal:%{public}p", data_value);
662    // 将符号位转化为int类型传出去
663    JSVM_Value returnValue = nullptr;
664    OH_JSVM_CreateInt32(env, 0, &returnValue);
665    return returnValue;
666}
667```
668
669ArkTS侧示例代码
670
671```ts
672import hilog from "@ohos.hilog"
673// 通过import的方式,引入Native能力。
674import napitest from "libentry.so"
675let script: string = `getValueExternal()`;
676try {
677  let result = napitest.runJsVm(script);
678  hilog.info(0x0000, 'testJSVM', 'Test JSVM getValueExternal: %{public}s', result);
679} catch (error) {
680  hilog.error(0x0000, 'testJSVM', 'Test JSVM getValueExternal error: %{public}s', error.message);
681}
682```
683
684### OH_JSVM_CreateSymbol
685
686用于创建一个新的Symbol。Symbol是一种特殊的数据类型,用于表示唯一的标识符。与字符串或数字不同,符号的值是唯一的,即使两个符号具有相同的描述,它们也是不相等的。符号通常用作对象属性的键,以确保属性的唯一性。
687
688cpp部分代码
689
690```cpp
691// hello.cpp
692#include "napi/native_api.h"
693#include "ark_runtime/jsvm.h"
694#include <hilog/log.h>
695// CreateSymbol注册回调
696static JSVM_CallbackStruct param[] = {
697    {.data = nullptr, .callback = CreateSymbol},
698};
699static JSVM_CallbackStruct *method = param;
700// CreateSymbol方法别名,供JS调用
701static JSVM_PropertyDescriptor descriptor[] = {
702    {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
703};
704// OH_JSVM_CreateSymbol的样例方法
705static JSVM_Value CreateSymbol(JSVM_Env env, JSVM_CallbackInfo info)
706{
707    JSVM_Value result = nullptr;
708    const char *des = "only";
709    OH_JSVM_CreateStringUtf8(env, des, JSVM_AUTO_LENGTH, &result);
710    JSVM_Value returnSymbol = nullptr;
711    OH_JSVM_CreateSymbol(env, result, &returnSymbol);
712    JSVM_Value returnValue = nullptr;
713    bool type = false;
714    JSVM_ValueType valuetypeSymbol;
715    OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol);
716    if (valuetypeSymbol == JSVM_SYMBOL) {
717        OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success");
718        type = true;
719    }
720    OH_JSVM_GetBoolean(env, type, &returnValue);
721    return returnValue;
722}
723```
724
725ArkTS侧示例代码
726
727```ts
728import hilog from "@ohos.hilog"
729// 通过import的方式,引入Native能力。
730import napitest from "libentry.so"
731let script: string = `createSymbol()`;
732try {
733  let result = napitest.runJsVm(script);
734  hilog.info(0x0000, 'testJSVM', 'Test JSVM createSymbol: %{public}s', result);
735} catch (error) {
736  hilog.error(0x0000, 'testJSVM', 'Test JSVM createSymbol error: %{public}s', error.message);
737}
738```
739
740### OH_JSVM_SymbolFor
741
742在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新Symbol
743
744cpp部分代码
745
746```cpp
747// hello.cpp
748#include "napi/native_api.h"
749#include "ark_runtime/jsvm.h"
750#include <hilog/log.h>
751// SymbolFor注册回调
752static JSVM_CallbackStruct param[] = {
753    {.data = nullptr, .callback = SymbolFor},
754};
755static JSVM_CallbackStruct *method = param;
756// SymbolFor方法别名,供JS调用
757static JSVM_PropertyDescriptor descriptor[] = {
758    {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
759};
760// 定义一个常量,用于存储最大字符串长度
761static const int MAX_BUFFER_SIZE = 128;
762// OH_JSVM_SymbolFor的样例方法
763static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info)
764{
765    JSVM_Value description = nullptr;
766    OH_JSVM_CreateStringUtf8(env, "test_demo", 9, &description);
767    char buffer[MAX_BUFFER_SIZE];
768    size_t bufferSize = MAX_BUFFER_SIZE;
769    size_t copied = 0;
770    OH_JSVM_GetValueStringUtf8(env, description, buffer, bufferSize, &copied);
771    JSVM_Value symbol = nullptr;
772    OH_JSVM_CreateSymbol(env, description, &symbol);
773    JSVM_Value result_symbol = nullptr;
774    JSVM_Status status = OH_JSVM_SymbolFor(env, nullptr, 0, &result_symbol);
775    JSVM_Value returnValue = nullptr;
776    bool type = false;
777    JSVM_ValueType valuetypeSymbol;
778    OH_JSVM_Typeof(env, result_symbol, &valuetypeSymbol);
779    if (valuetypeSymbol == JSVM_SYMBOL && status == JSVM_OK) {
780        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SymbolFor success");
781        type = true;
782    }
783    OH_JSVM_GetBoolean(env, type, &returnValue);
784    // 返回结果
785    return returnValue;
786}
787```
788
789ArkTS侧示例代码
790
791```ts
792import hilog from "@ohos.hilog"
793// 通过import的方式,引入Native能力。
794import napitest from "libentry.so"
795let script: string = `symbolFor()`;
796try {
797  let result = napitest.runJsVm(script);
798  hilog.info(0x0000, 'testJSVM', 'Test JSVM symbolFor: %{public}s', result);
799} catch (error) {
800  hilog.error(0x0000, 'testJSVM', 'Test JSVM symbolFor error: %{public}s', error.message);
801}
802```
803