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注册回调
47// OH_JSVM_GetPrototype的样例方法
48static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info)
49{
50    size_t argc = 1;
51    JSVM_Value argv[1] = {nullptr};
52    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
53    JSVM_Value result{nullptr};
54    JSVM_Status status = OH_JSVM_GetPrototype(env, argv[0], &result);
55    if (status != JSVM_OK) {
56        OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail");
57    } else {
58        OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success");
59    }
60    return result;
61}
62static JSVM_CallbackStruct param[] = {
63    {.data = nullptr, .callback = GetPrototype},
64};
65static JSVM_CallbackStruct *method = param;
66// GetPrototype方法别名,供JS调用
67static JSVM_PropertyDescriptor descriptor[] = {
68    {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
69};
70// 样例测试js
71const char* srcCallNative = R"JS(const myObject = {};
72    const proto = getPrototype(myObject);
73    console.log(proto === Object.prototype);)JS";
74```
75
76预期的输出结果
77```ts
78JSVM GetPrototype success
79```
80
81### OH_JSVM_CreateObject
82
83创建一个默认的JavaScript Object对象。
84
85cpp部分代码
86
87```cpp
88// hello.cpp
89#include "napi/native_api.h"
90#include "ark_runtime/jsvm.h"
91#include <hilog/log.h>
92// OH_JSVM_CreateObject的样例方法
93static JSVM_Value CreateObject(JSVM_Env env, JSVM_CallbackInfo info)
94{
95    JSVM_Value object = nullptr;
96    // 创建一个空对象
97    JSVM_Status status = OH_JSVM_CreateObject(env, &object);
98    if (status != JSVM_OK) {
99        OH_LOG_ERROR(LOG_APP, "JSVM CreateObject fail");
100    } else {
101        OH_LOG_INFO(LOG_APP, "JSVM CreateObject success");
102    }
103    // 设置对象的属性
104    JSVM_Value name = nullptr;
105    // 设置属性名为 "name"
106    OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &name);
107    JSVM_Value value = nullptr;
108    // 设置属性值为 "Hello from N-API!"
109    OH_JSVM_CreateStringUtf8(env, "Hello OH_JSVM_CreateObject!", JSVM_AUTO_LENGTH, &value);
110    // 将属性设置到对象上
111    OH_JSVM_SetProperty(env, object, name, value);
112    return object;
113}
114// CreateObject注册回调
115static JSVM_CallbackStruct param[] = {
116    {.data = nullptr, .callback = CreateObject},
117};
118static JSVM_CallbackStruct *method = param;
119// CreateObject方法别名,供JS调用
120static JSVM_PropertyDescriptor descriptor[] = {
121    {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
122};
123// 样例测试js
124const char* srcCallNative = R"JS(createObject())JS";
125```
126
127预期的输出结果
128```ts
129JSVM CreateObject success
130```
131
132### OH_JSVM_ObjectFreeze
133
134冻结给定的对象,防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。
135
136cpp部分代码
137
138```cpp
139// hello.cpp
140#include "napi/native_api.h"
141#include "ark_runtime/jsvm.h"
142#include <hilog/log.h>
143// OH_JSVM_ObjectFreeze的样例方法
144static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info)
145{
146    // 接受一个JavaScript侧传入的object
147    size_t argc = 1;
148    JSVM_Value argv[1] = {nullptr};
149    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
150    // 调用接口OH_JSVM_ObjectFreeze将传入的object冻结
151    JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]);
152    if (status == JSVM_OK) {
153        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success");
154    }
155    // 测试冻结后的对象中属性能否修改
156    JSVM_Value value = nullptr;
157    OH_JSVM_CreateInt32(env, 111111, &value);
158    OH_JSVM_SetNamedProperty(env, argv[0], "data", value);
159    // 将冻结后修改过的属性返回JavaScript侧
160    return argv[0];
161}
162// ObjectFreeze注册回调
163static JSVM_CallbackStruct param[] = {
164    {.data = nullptr, .callback = ObjectFreeze},
165};
166static JSVM_CallbackStruct *method = param;
167// ObjectFreeze方法别名,供JS调用
168static JSVM_PropertyDescriptor descriptor[] = {
169    {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
170};
171// 样例测试js
172const char* srcCallNative = R"JS(let obj = { data: 55, message: "hello world"};
173  objectFreeze(obj))JS";
174```
175
176预期的输出结果
177```ts
178Test JSVM OH_JSVM_ObjectFreeze success
179```
180
181### OH_JSVM_ObjectSeal
182
183密封给定的对象。这可以防止向其添加新属性,以及将所有现有属性标记为不可配置。
184
185cpp部分代码
186
187```cpp
188// hello.cpp
189#include "napi/native_api.h"
190#include "ark_runtime/jsvm.h"
191#include <hilog/log.h>
192// OH_JSVM_ObjectSeal的样例方法
193static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info)
194{
195    // 接受一个JavaScript侧传入的object
196    size_t argc = 1;
197    JSVM_Value argv[1] = {nullptr};
198    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
199    // 调用接口OH_JSVM_ObjectSeal将传入的object封闭,使其无法添加新的属性
200    JSVM_Status status = OH_JSVM_ObjectSeal(env, argv[0]);
201    if (status == JSVM_OK) {
202        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal success");
203    }
204    // 检查封闭后的对象中属性能否修改、删除、新增
205    // 封闭后对象修改
206    JSVM_Value changeValue = nullptr;
207    OH_JSVM_CreateInt32(env, 111111, &changeValue);
208    OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue);
209    // 封闭后对象删除
210    JSVM_Value deleteProperty = nullptr;
211    OH_JSVM_CreateStringUtf8(env, "message", JSVM_AUTO_LENGTH, &deleteProperty);
212    bool result = false;
213    OH_JSVM_DeleteProperty(env, argv[0], deleteProperty, &result);
214    if (result) {
215        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed");
216    }
217    // 封闭后对象新增
218    JSVM_Value addValue = nullptr;
219    OH_JSVM_CreateStringUtf8(env, "addValue", JSVM_AUTO_LENGTH, &addValue);
220    OH_JSVM_SetNamedProperty(env, argv[0], "newProperty", addValue);
221    // 将封闭后改动过的对象返回JavaScript侧
222    return argv[0];
223}
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// 样例测试js
234const char* srcCallNative = R"JS( let obj = { data: 55, message: "hello world"};
235  objectSeal(obj))JS";
236```
237
238预期的输出结果
239```ts
240Test JSVM OH_JSVM_ObjectSeal success
241```
242
243### OH_JSVM_Typeof
244
245返回JavaScript对象的类型。
246
247cpp部分代码
248
249```cpp
250// hello.cpp
251#include "napi/native_api.h"
252#include "ark_runtime/jsvm.h"
253#include <hilog/log.h>
254// OH_JSVM_Typeof的样例方法
255static JSVM_Value GetTypeof(JSVM_Env env, JSVM_CallbackInfo info) {
256    size_t argc = 1;
257    JSVM_Value args[1] = {nullptr};
258    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
259    JSVM_ValueType valueType;
260    OH_JSVM_Typeof(env, args[0], &valueType);
261    JSVM_Value type = nullptr;
262    switch (valueType) {
263    case JSVM_UNDEFINED:
264        OH_LOG_INFO(LOG_APP, "JSVM Input type is undefined");
265        OH_JSVM_CreateStringUtf8(env, "Input type is undefined", JSVM_AUTO_LENGTH, &type);
266        break;
267    case JSVM_NULL:
268        OH_LOG_INFO(LOG_APP, "JSVM Input type is null");
269        OH_JSVM_CreateStringUtf8(env, "Input type is null", JSVM_AUTO_LENGTH, &type);
270        break;
271    case JSVM_BOOLEAN:
272        OH_LOG_INFO(LOG_APP, "JSVM Input type is boolean");
273        OH_JSVM_CreateStringUtf8(env, "Input type is boolean", JSVM_AUTO_LENGTH, &type);
274        break;
275    case JSVM_NUMBER:
276        OH_LOG_INFO(LOG_APP, "JSVM Input type is number");
277        OH_JSVM_CreateStringUtf8(env, "Input type is number", JSVM_AUTO_LENGTH, &type);
278        break;
279    case JSVM_STRING:
280        OH_LOG_INFO(LOG_APP, "JSVM Input type is string");
281        OH_JSVM_CreateStringUtf8(env, "Input type is string", JSVM_AUTO_LENGTH, &type);
282        break;
283    case JSVM_SYMBOL:
284        OH_LOG_INFO(LOG_APP, "JSVM Input type is symbol");
285        OH_JSVM_CreateStringUtf8(env, "Input type is symbol", JSVM_AUTO_LENGTH, &type);
286        break;
287    case JSVM_OBJECT:
288        OH_LOG_INFO(LOG_APP, "JSVM Input type is object");
289        OH_JSVM_CreateStringUtf8(env, "Input type is object", JSVM_AUTO_LENGTH, &type);
290        break;
291    case JSVM_FUNCTION:
292        OH_LOG_INFO(LOG_APP, "JSVM Input type is function");
293        OH_JSVM_CreateStringUtf8(env, "Input type is function", JSVM_AUTO_LENGTH, &type);
294        break;
295    case JSVM_EXTERNAL:
296        OH_LOG_INFO(LOG_APP, "JSVM Input type is external");
297        OH_JSVM_CreateStringUtf8(env, "Input type is external", JSVM_AUTO_LENGTH, &type);
298        break;
299    case JSVM_BIGINT:
300        OH_LOG_INFO(LOG_APP, "JSVM Input type is bigint");
301        OH_JSVM_CreateStringUtf8(env, "Input type is bigint", JSVM_AUTO_LENGTH, &type);
302        break;
303    default:
304        OH_LOG_INFO(LOG_APP, "JSVM Input type does not match any");
305        OH_JSVM_CreateStringUtf8(env, " ", JSVM_AUTO_LENGTH, &type);
306        break;
307    }
308    return type;
309}
310// GetTypeof注册回调
311static JSVM_CallbackStruct param[] = {
312    {.data = nullptr, .callback = GetTypeof},
313};
314static JSVM_CallbackStruct *method = param;
315// GetTypeof方法别名,TS侧调用
316static JSVM_PropertyDescriptor descriptor[] = {
317    {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
318};
319// 样例测试js
320const char* srcCallNative = R"JS(getTypeof(true);)JS";
321```
322
323预期的输出结果
324```ts
325JSVM Input type is boolean
326```
327
328### OH_JSVM_Instanceof
329
330判断一个对象是否是某个构造函数的实例。
331
332cpp部分代码
333
334```cpp
335// hello.cpp
336#include "napi/native_api.h"
337#include "ark_runtime/jsvm.h"
338#include <hilog/log.h>
339// OH_JSVM_Instanceof的样例方法
340static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info)
341{
342    // 获取两个JavaScript侧传入的参数
343    size_t argc = 2;
344    JSVM_Value args[2] = {nullptr};
345    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
346    bool result = false;
347    JSVM_Status status = OH_JSVM_Instanceof(env, args[0], args[1], &result);
348    if (status != JSVM_OK) {
349        OH_LOG_ERROR(LOG_APP, "JSVM InstanceOf fail");
350    } else {
351        OH_LOG_INFO(LOG_APP, "JSVM InstanceOf:%{public}d", result);
352    }
353    JSVM_Value returnValue = nullptr;
354    OH_JSVM_GetBoolean(env, result, &returnValue);
355    return returnValue;
356}
357// InstanceOf注册回调
358static JSVM_CallbackStruct param[] = {
359    {.data = nullptr, .callback = InstanceOf},
360};
361static JSVM_CallbackStruct *method = param;
362// InstanceOf方法别名,TS侧调用
363static JSVM_PropertyDescriptor descriptor[] = {
364    {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
365};
366// 样例测试js
367const char* srcCallNative = R"JS(class Person {
368        name;
369        age;
370        constructor(name, age) {
371          this.name = name;
372          this.age = age;
373        }
374      }
375     instanceOf(new Person('Alice', 30), Person);
376     ;)JS";
377```
378
379预期的输出结果
380```ts
381JSVM InstanceOf:1
382```
383
384### OH_JSVM_TypeTagObject
385
386使用类型标签type_tag来标记JavaScript对象,后续可以更精确地识别JavaScript对象。
387
388### OH_JSVM_CheckObjectTypeTag
389
390检查给定的类型标签是否与对象上的类型标签匹配。
391
392cpp部分代码
393
394```cpp
395// hello.cpp
396#include "napi/native_api.h"
397#include "ark_runtime/jsvm.h"
398#include <hilog/log.h>
399#define NUMBERINT_FOUR 4
400// 定义一个静态常量JSVM_TypeTag数组存储类型标签
401static const JSVM_TypeTag TagsData[NUMBERINT_FOUR] = {
402    {0x9e4b2449547061b3, 0x33999f8a6516c499},
403    {0x1d55a794c53a726d, 0x43633f509f9c944e},
404    {0, 0}, // 用于表示无标签或默认标签
405    {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0},
406};
407// OH_JSVM_TypeTagObject的样例方法
408static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info)
409{
410    // 获取两个JavaScript侧传入的参数
411    size_t argc = 2;
412    JSVM_Value args[2] = {nullptr};
413    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
414    // 获取索引数字转换为JSVM_Value
415    int32_t index = 0;
416    OH_JSVM_GetValueInt32(env, args[1], &index);
417    // 给参数(对象)设置类型标签
418    JSVM_Status status = OH_JSVM_TypeTagObject(env, args[0], &TagsData[index]);
419    // 将bool结果转换为JSVM_Value并返回
420    JSVM_Value result = nullptr;
421    if (status != JSVM_OK) {
422        OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail");
423        OH_JSVM_GetBoolean(env, false, &result);
424    } else {
425        OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success");
426        OH_JSVM_GetBoolean(env, true, &result);
427    }
428    return result;
429}
430// OH_JSVM_CheckObjectTypeTag的样例方法
431static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info)
432{
433    // 获取两个JavaScript侧传入的参数
434    size_t argc = 2;
435    JSVM_Value args[2] = {nullptr};
436    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
437    // 获取索引数字转换为JSVM_Value
438    int32_t index = 0;
439    OH_JSVM_GetValueInt32(env, args[1], &index);
440    // 检查对象的类型标签
441    bool checkResult = false;
442    JSVM_Status status = OH_JSVM_CheckObjectTypeTag(env, args[0], &TagsData[index], &checkResult);
443    if (status != JSVM_OK) {
444        OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail");
445    } else {
446        OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject:%{public}d", checkResult);
447    }
448    // 将bool结果转换为JSVM_Value并返回
449    JSVM_Value checked = nullptr;
450    OH_JSVM_GetBoolean(env, checkResult, &checked);
451    return checked;
452}
453// SetTypeTagToObject,CheckObjectTypeTag注册回调
454static JSVM_CallbackStruct param[] = {
455    {.data = nullptr, .callback = SetTypeTagToObject},
456    {.data = nullptr, .callback = CheckObjectTypeTag},
457};
458static JSVM_CallbackStruct *method = param;
459// SetTypeTagToObject,CheckObjectTypeTag方法别名,TS侧调用
460static JSVM_PropertyDescriptor descriptor[] = {
461    {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
462    {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
463};
464// 样例测试js
465const char* srcCallNative = R"JS(
466         class Obj {
467           data;
468           message;
469         }
470         let obj= { data: 0, message: "hello world"};
471         setTypeTagToObject(obj, 0);
472         checkObjectTypeTag(obj,0);)JS";
473```
474
475预期的输出结果
476```ts
477JSVM SetTypeTagToObject success
478JSVM SetTypeTagToObject:1
479```
480
481### OH_JSVM_CreateExternal
482
483创建一个包装了外部指针的JavaScript对象。
484**注意**:JavaScript对象被垃圾回收时,包装的外部指针指向的内容不被GC直接管理,仅调用传入的第三个参数对应的函数(如果传入时不为nullptr)。
485
486cpp部分代码
487
488```cpp
489// hello.cpp
490#include "napi/native_api.h"
491#include "ark_runtime/jsvm.h"
492#include <hilog/log.h>
493// OH_JSVM_CreateExternal的样例方法
494static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info)
495{
496    size_t dataSize = 10;
497    void *data = malloc(dataSize);
498    if (data == nullptr) {
499        OH_LOG_ERROR(LOG_APP, "JSVM Failed to malloc.");
500        return nullptr;
501    }
502    memset(data, 0, dataSize);
503    const char* testStr = "test";
504    JSVM_Value external = nullptr;
505    JSVM_Status status = OH_JSVM_CreateExternal(
506        env, data, [](JSVM_Env env, void *data, void *hint) {free(data);}, (void *)testStr, &external);
507    if (status != JSVM_OK) {
508        OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status);
509        free(data);
510        data = nullptr;
511        return nullptr;
512    } else {
513        OH_LOG_INFO(LOG_APP, "JSVM CreateExternal success");
514    }
515    return external;
516}
517// CreateExternal注册回调
518static JSVM_CallbackStruct param[] = {
519    {.data = nullptr, .callback = CreateExternal},
520};
521static JSVM_CallbackStruct *method = param;
522// CreateExternal方法别名,供JS调用
523static JSVM_PropertyDescriptor descriptor[] = {
524    {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
525};
526// 样例测试js
527const char* srcCallNative = R"JS(createExternal())JS";
528```
529
530预期的输出结果
531```ts
532JSVM CreateExternal success
533```
534
535### OH_JSVM_GetValueExternal
536
537OH_JSVM_CreateExternal可以创建包装自定义的C/C++对象并将其公开给JavaScript代码,而OH_JSVM_GetValueExternal就是用来获得OH_JSVM_CreateExternal所包装的外部对象的指针。
538
539cpp部分代码
540
541```cpp
542// hello.cpp
543#include "napi/native_api.h"
544#include "ark_runtime/jsvm.h"
545#include <hilog/log.h>
546// OH_JSVM_GetValueExternal的样例方法
547static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info)
548{
549    static int data = 0x12345;
550    JSVM_Value externalValue = nullptr;
551    JSVM_Status status = OH_JSVM_CreateExternal(env, (void*)&data, nullptr, nullptr, &externalValue);
552    if (status != JSVM_OK) {
553        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail");
554    } else {
555        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateExternal success");
556    }
557    void *data_value;
558    status = OH_JSVM_GetValueExternal(env, externalValue, &data_value);
559    if (status != JSVM_OK) {
560        OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail");
561    } else {
562        OH_LOG_INFO(LOG_APP, "JSVM GetValueExternal success");
563    }
564    // 将符号位转化为int类型传出去
565    JSVM_Value returnValue = nullptr;
566    int retData = *static_cast<int *>(data_value);
567    OH_JSVM_CreateInt32(env, retData, &returnValue);
568    return returnValue;
569}
570// GetValueExternal注册回调
571static JSVM_CallbackStruct param[] = {
572    {.data = nullptr, .callback = GetValueExternal},
573};
574static JSVM_CallbackStruct *method = param;
575// GetValueExternal方法别名,供JS调用
576static JSVM_PropertyDescriptor descriptor[] = {
577    {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
578};
579// 样例测试js
580const char* srcCallNative = R"JS(getValueExternal())JS";
581```
582
583预期的输出结果
584```ts
585JSVM OH_JSVM_CreateExternal success
586JSVM GetValueExternal success
587```
588
589### OH_JSVM_CreateSymbol
590
591用于创建一个新的Symbol。Symbol是一种特殊的数据类型,用于表示唯一的标识符。与字符串或数字不同,符号的值是唯一的,即使两个符号具有相同的描述,它们也是不相等的。符号通常用作对象属性的键,以确保属性的唯一性。
592
593cpp部分代码
594
595```cpp
596// hello.cpp
597#include "napi/native_api.h"
598#include "ark_runtime/jsvm.h"
599#include <hilog/log.h>
600// OH_JSVM_CreateSymbol的样例方法
601static JSVM_Value CreateSymbol(JSVM_Env env, JSVM_CallbackInfo info)
602{
603    JSVM_Value result = nullptr;
604    const char *des = "only";
605    OH_JSVM_CreateStringUtf8(env, des, JSVM_AUTO_LENGTH, &result);
606    JSVM_Value returnSymbol = nullptr;
607    OH_JSVM_CreateSymbol(env, result, &returnSymbol);
608    JSVM_ValueType valuetypeSymbol;
609    OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol);
610    if (valuetypeSymbol == JSVM_SYMBOL) {
611        OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success");
612    } else {
613        OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol fail");
614    }
615    return returnSymbol;
616}
617// CreateSymbol注册回调
618static JSVM_CallbackStruct param[] = {
619    {.data = nullptr, .callback = CreateSymbol},
620};
621static JSVM_CallbackStruct *method = param;
622// CreateSymbol方法别名,供JS调用
623static JSVM_PropertyDescriptor descriptor[] = {
624    {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
625};
626// 样例测试js
627const char* srcCallNative = R"JS(createSymbol())JS";
628```
629
630预期的输出结果
631```ts
632JSVM CreateSymbol Success
633```
634
635### OH_JSVM_SymbolFor
636
637在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新Symbol。
638
639cpp部分代码
640
641```cpp
642// hello.cpp
643#include "napi/native_api.h"
644#include "ark_runtime/jsvm.h"
645#include <hilog/log.h>
646// 定义一个常量,用于存储最大字符串长度
647static const int MAX_BUFFER_SIZE = 128;
648// OH_JSVM_SymbolFor的样例方法
649static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info)
650{
651    JSVM_Value description = nullptr;
652    OH_JSVM_CreateStringUtf8(env, "test_demo", 9, &description);
653    char buffer[MAX_BUFFER_SIZE];
654    size_t bufferSize = MAX_BUFFER_SIZE;
655    size_t copied = 0;
656    OH_JSVM_GetValueStringUtf8(env, description, buffer, bufferSize, &copied);
657    JSVM_Value symbol = nullptr;
658    OH_JSVM_CreateSymbol(env, description, &symbol);
659    JSVM_Value result_symbol = nullptr;
660    JSVM_Status status = OH_JSVM_SymbolFor(env, buffer, copied, &result_symbol);
661    JSVM_ValueType valuetypeSymbol;
662    OH_JSVM_Typeof(env, result_symbol, &valuetypeSymbol);
663    if (valuetypeSymbol == JSVM_SYMBOL && status == JSVM_OK) {
664        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SymbolFor success");
665    }
666    // 返回结果
667    return result_symbol;
668}
669// SymbolFor注册回调
670static JSVM_CallbackStruct param[] = {
671    {.data = nullptr, .callback = SymbolFor},
672};
673static JSVM_CallbackStruct *method = param;
674// SymbolFor方法别名,供JS调用
675static JSVM_PropertyDescriptor descriptor[] = {
676    {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
677};
678// 样例测试js
679const char* srcCallNative = R"JS(symbolFor())JS";
680```
681
682预期的输出结果
683```ts
684JSVM OH_JSVM_SymbolFor success
685```
686