使用JSVM-API接口进行array相关开发
=======================

#### 简介

使用JSVM-API接口进行数组（array）相关开发时，在JSVM模块中可以调用相关接口直接操作和处理JavaScript中的数组。

#### 基本概念

使用 JSVM-API 接口进行数组（array）相关开发时，涉及的基本概念主要包括数组的创建、访问、修改、遍历以及与数组相关的操作。这些概念对于理解在 JSVM 模块中与 JavaScript 数组交互非常重要。以下是一些关键概念：

*   **数组的创建**：若在 JSVM 模块中需要创建新的 JavaScript 数组时，可以使用提供的 OH\_JSVM\_CreateArray 接口创建数组，将传递给 JavaScript 层。
*   **数组相关操作**：在 JSVM 模块中通过对应的接口获取 JavaScript 数组的长度、检索指定索引处的元素、设置指定索引的元素值，从而实现 JSVM 模块与 JavaScript 数组的交互。
*   **TypedArray**：JavaScript 中的 TypedArray 是一种类数组数据视图，用于描述二进制数据。它可以视为指定元素类型的类数组数据视图，TypedArray 没有直接构造器，但是可以通过其子类构造器构造创建。子类包括：Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Int32Array等。
*   **ArrayBuffer**：ArrayBuffer 是固定长度的二进制数据缓冲区。
*   **DataView**：DataView 是 JavaScript 中的一种视图，是可以从 ArrayBuffer 对象中读写多种数值类型的底层接口。

#### 接口说明

| 接口 | 功能说明 |
| :-- | :-- |
| OH\_JSVM\_CreateArray | 创建一个新的 JavaScript 数组对象 |
| OH\_JSVM\_CreateArrayWithLength | 创建一个指定长度的 JavaScript 数组对象 |
| OH\_JSVM\_CreateTypedarray | 在现有的ArrayBuffer上创建JavaScript TypedArray对象，TypedArray对象提供类似类数组的视图，每个元素具有相同的二进制标量数据类型。注意(length \* size\_of\_element) + byte\_offset 不得超过传入数组的大小（以字节为单位），否则会引发RangeError异常。 |
| OH\_JSVM\_CreateDataview | 在现有的 ArrayBuffer 上创建一个 JavaScript DataView 对象，DataView 对象在底层数据缓冲区上提供类似数组的视图，该 ArrayBuffer 允许有不同大小和类型的元素。要求 byte\_length + byte\_offset 小于或等于传入数组的字节大小，否则会引发 RangeError 异常。 |
| OH\_JSVM\_GetArrayLength | 返回 Array 对象的长度 |
| OH\_JSVM\_GetTypedarrayInfo | 获取 TypedArray（类型化数组）对象的信息 |
| OH\_JSVM\_GetDataviewInfo | 获取 DataView 对象的信息 |
| OH\_JSVM\_IsArray | 判断一个 JavaScript 对象是否为 Array 类型对象 |
| OH\_JSVM\_SetElement | 在给定对象的指定索引处设置元素 |
| OH\_JSVM\_GetElement | 获取给定对象指定索引处的元素 |
| OH\_JSVM\_HasElement | 若给定对象的指定索引处拥有属性，获取该元素 |
| OH\_JSVM\_DeleteElement | 尝试删除给定对象的指定索引处的元素 |
| OH\_JSVM\_IsDataview | 判断一个 JavaScript 对象是否为 DataView 类型对象 |
| OH\_JSVM\_IsTypedarray | 判断一个 JavaScript 对象是否为 TypedArray 类型对象 |

#### 使用示例

JSVM-API 接口开发流程参考[使用 JSVM-API 实现 JS 与 C/C++ 语言交互开发流程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-jsvm-process)，本文仅对接口对应 C++ 相关代码进行展示。

#### \[h2\]OH\_JSVM\_CreateArray

创建一个新的 JavaScript 数组对象。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// CreateArray注册回调
static int DIFF\_VALUE\_FIVE = 5;
// OH\_JSVM\_CreateArray的样例方法
static JSVM\_Value CreateArray(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 创建一个空数组
    JSVM\_Value array = nullptr;
    JSVM\_Status status = OH\_JSVM\_CreateArray(env, &array);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateArray fail");
        return nullptr;
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateArray success");
    }
    // 对创建的数组进行赋值
    for (int i = 0; i < DIFF\_VALUE\_FIVE; i++) {
        JSVM\_Value element;
        JSVM\_CALL(OH\_JSVM\_CreateInt32(env, i, &element));
        JSVM\_CALL(OH\_JSVM\_SetElement(env, array, i, element));
    }
    return array;
}
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateArray},
};
static JSVM\_CallbackStruct \*method = param;
// CreateArray方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
  function testCreateArray() {
    return createArray();
  }
  testCreateArray();
)JS";

预计的输出结果：

JSVM CreateArray success

#### \[h2\]OH\_JSVM\_CreateArrayWithLength

创建一个指定长度的 JavaScript 数组对象。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_CreateArrayWithLength的样例方法
static JSVM\_Value CreateArrayWithLength(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value argv\[1\] = {nullptr};
    JSVM\_Value result = nullptr;
    // 解析传递的参数OH\_JSVM\_GetCbInfo
    OH\_JSVM\_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    // 获取传递的数组长度
    int32\_t length = 0;
    OH\_JSVM\_GetValueInt32(env, argv\[0\], &length);
    // 使用OH\_JSVM\_CreateArrayWithLength创建传递固定长度的数组
    JSVM\_Status status = OH\_JSVM\_CreateArrayWithLength(env, length, &result);
    if (status == JSVM\_OK) {
        // 给创建的数组设置值
        for (int32\_t i = 0; i < length; i++) {
            JSVM\_Value value;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, i, &value));
            JSVM\_CALL(OH\_JSVM\_SetElement(env, result, i, value));
        }
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateArrayWithLength success");
    } else {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateArrayWithLength fail");
    }
    return result;
}
// CreateArrayWithLength注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateArrayWithLength},
};
static JSVM\_CallbackStruct \*method = param;
// CreateArrayWithLength方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createArrayWithLength", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let num = 7;
function testCreateArrayWithLength(num){
    return createArrayWithLength(num);
}
testCreateArrayWithLength(num);
)JS";

预计的输出结果：

JSVM CreateArrayWithLength success

#### \[h2\]OH\_JSVM\_CreateTypedarray

在现有的 ArrayBuffer上 创建一个 JavaScript TypedArray 对象,TypedArray 对象在底层数据缓冲区上提供类似数组的视图，其中每个元素都具有相同的底层二进制标量数据类型。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_CreateTypedarray的样例方法
static int DIFF\_VALUE\_THREE = 3;
static JSVM\_Value CreateTypedArray(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    int32\_t typeNum = 0;
    OH\_JSVM\_GetValueInt32(env, args\[0\], &typeNum);
    JSVM\_TypedarrayType arrayType;
    // 用于存储每个元素的大小
    size\_t elementSize = 0;
    // 转换为JSVM\_TypedarrayType类型
    arrayType = static\_cast<JSVM\_TypedarrayType>(typeNum);
    switch (typeNum) {
        case JSVM\_INT8\_ARRAY:
        case JSVM\_UINT8\_ARRAY:
        case JSVM\_UINT8\_CLAMPED\_ARRAY:
            elementSize = sizeof(int8\_t);
            break;
        case JSVM\_INT16\_ARRAY:
        case JSVM\_UINT16\_ARRAY:
            elementSize = sizeof(int16\_t);
            break;
        case JSVM\_INT32\_ARRAY:
        case JSVM\_UINT32\_ARRAY:
            elementSize = sizeof(int32\_t);
            break;
        case JSVM\_FLOAT32\_ARRAY:
            elementSize = sizeof(float);
            break;
        case JSVM\_FLOAT64\_ARRAY:
            elementSize = sizeof(double);
            break;
        case JSVM\_BIGINT64\_ARRAY:
        case JSVM\_BIGUINT64\_ARRAY:
            elementSize = sizeof(int64\_t);
            break;
        default:
            // 默认创建JSVM\_INT8\_ARRAY类型
            arrayType = JSVM\_INT8\_ARRAY;
            elementSize = sizeof(int8\_t);
            break;
    }
    size\_t length = DIFF\_VALUE\_THREE;
    JSVM\_Value arrayBuffer = nullptr;
    JSVM\_Value typedArray = nullptr;
    void \*data;
    // 创建一个ArrayBuffer
    OH\_JSVM\_CreateArraybuffer(env, length \* elementSize, (void \*\*)&data, &arrayBuffer);
    // 根据给定类型创建TypedArray
    JSVM\_Status status = OH\_JSVM\_CreateTypedarray(env, arrayType, length, arrayBuffer, 0, &typedArray);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateTypedArray fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateTypedArray success");
    }
    return typedArray;
}
// CreateTypedArray注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateTypedArray},
};
static JSVM\_CallbackStruct \*method = param;
// CreateTypedArray方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createTypedArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
const type = {
    INT8\_ARRAY: 0,
    UINT8\_ARRAY: 1,
    UINT8\_CLAMPED\_ARRAY: 2,
    INT16\_ARRAY: 3,
    UINT16\_ARRAY: 4,
    INT32\_ARRAY: 5,
    UINT32\_ARRAY: 6,
    FLOAT32\_ARRAY: 7,
    FLOAT64\_ARRAY: 8,
    BIGINT64\_ARRAY: 9,
    BIGUINT64\_ARRAY: 10
};
createTypedArray(type.INT8\_ARRAY);
createTypedArray(type.INT32\_ARRAY);
)JS";

预计的输出结果：

JSVM CreateTypedArray success
JSVM CreateTypedArray success

#### \[h2\]OH\_JSVM\_CreateDataview

在现有的 ArrayBuffer 上创建一个 JavaScript DataView 对象，DataView 对象在底层数据缓冲区上提供类似数组的视图。

cpp 部分代码：

static int DIFF\_VALUE\_FOUR = 4;
static int DIFF\_VALUE\_TWELVE = 12;
// OH\_JSVM\_CreateDataview的样例方法
static JSVM\_Value CreateDataView(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 获取js侧传入的两个参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    JSVM\_Value arrayBuffer = nullptr;
    JSVM\_Value result = nullptr;
    // DataView的字节长度
    size\_t byteLength = DIFF\_VALUE\_TWELVE;
    // 字节偏移量
    size\_t byteOffset = DIFF\_VALUE\_FOUR;
    // 获取回调函数的参数信息
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 将参数转换为对象类型
    OH\_JSVM\_CoerceToObject(env, args\[0\], &arrayBuffer);
    // 创建一个数据视图对象，并指定字节长度和字节偏移量
    JSVM\_Status status = OH\_JSVM\_CreateDataview(env, byteLength, arrayBuffer, byteOffset, &result);
    // 获取DataView的指针和长度信息
    uint8\_t \*data = nullptr;
    // 为DataView赋值
    int32\_t infoType = 0;
    OH\_JSVM\_GetValueInt32(env, args\[1\], &infoType);
    size\_t returnLength = 0;
    JSVM\_Value returnArrayBuffer = nullptr;
    size\_t returnOffset = 0;
    enum InfoType { BYTE\_LENGTH, ARRAY\_BUFFER, BYTE\_OFFSET };
    // 获取dataview信息
    OH\_JSVM\_GetDataviewInfo(env, result, &returnLength, (void \*\*)&data, &returnArrayBuffer, &returnOffset);
    JSVM\_Value returnResult = nullptr;
    switch (infoType) {
        case BYTE\_LENGTH:
            JSVM\_Value len;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, returnLength, &len));
            returnResult = len;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateDataView fail");
            } else {
                OH\_LOG\_INFO(LOG\_APP, "JSVM CreateDataView success, returnLength: %{public}d", returnLength);
            }
            break;
        case ARRAY\_BUFFER:
            {
                bool isArraybuffer = false;
                JSVM\_CALL(OH\_JSVM\_IsArraybuffer(env, returnArrayBuffer, &isArraybuffer));
                JSVM\_Value isArray;
                OH\_JSVM\_GetBoolean(env, isArraybuffer, &isArray);
                returnResult = isArray;
                if (status != JSVM\_OK) {
                    OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateDataView fail");
                } else {
                    OH\_LOG\_INFO(LOG\_APP, "JSVM CreateDataView success, isArraybuffer: %{public}d", isArraybuffer);
                }
                break;
            }
        case BYTE\_OFFSET:
            JSVM\_Value offset;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, returnOffset, &offset));
            returnResult = offset;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateDataView fail");
            } else {
                OH\_LOG\_INFO(LOG\_APP, "JSVM CreateDataView success, returnOffset: %{public}d", returnOffset);
            }
            break;
        default:
            break;
    }
    return returnResult;
}
// CreateDataView注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateDataView},
};
static JSVM\_CallbackStruct \*method = param;
// CreateDataView方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createDataView", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
 let BYTE\_LENGTH = 0;
 createDataView(new ArrayBuffer(16), BYTE\_LENGTH);
 let IS\_ARRAYBUFFER = 1;
 createDataView(new ArrayBuffer(16), IS\_ARRAYBUFFER);
 let BYTE\_OFFSET = 2;
 createDataView(new ArrayBuffer(16), BYTE\_OFFSET);
)JS";

预计的输出结果：

CreateDataView success, returnLength: 12
JSVM CreateDataView success, isArraybuffer: 1
JSVM CreateDataView success, returnOffset: 4

#### \[h2\]OH\_JSVM\_GetArrayLength

返回 Array 对象的长度。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_GetArrayLength的样例方法
static JSVM\_Value GetArrayLength(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    JSVM\_Value result = nullptr;
    // 这里要对length进行初始化
    uint32\_t length = 0;
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 检查参数是否为数组
    bool isArray = false;
    OH\_JSVM\_IsArray(env, args\[0\], &isArray);
    if (!isArray) {
        OH\_LOG\_INFO(LOG\_APP, "JSVM Argument must be an array");
        return nullptr;
    }
    /\*
     \* 当成功获取数组长度时，length会被赋值成实际JSArray的长度，接口返回JSVM\_OK状态码；
     \* 当args\[0\]不是一个JSArray类型。例如，当args\[0\]是一个proxy对象时，无法获取长度。
     \* 此时，length维持原值不变，接口返回JSVM\_ARRAY\_EXPECTED状态码。
     \*/
    JSVM\_Status status = OH\_JSVM\_GetArrayLength(env, args\[0\], &length);
    if (status == JSVM\_OK) {
        // 创建返回值
        JSVM\_CALL(OH\_JSVM\_CreateInt32(env, length, &result));
        OH\_LOG\_INFO(LOG\_APP, "JSVM length: %{public}d", length);
    }
    return result;
}
// GetArrayLength注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetArrayLength},
};
static JSVM\_CallbackStruct \*method = param;
// GetArrayLength方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getArrayLength", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let data = \[0, 1, 2, 3, 4, 5\];
getArrayLength(data);
)JS";

预计的输出结果：

JSVM length: 6

#### \[h2\]OH\_JSVM\_GetTypedarrayInfo

获取 TypedArray（类型化数组）对象的信息。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_GetTypedarrayInfo的样例方法
static JSVM\_Value GetTypedArrayInfo(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 获取并解析参数，第一个参数为需要获得的信息的TypedArray类型数据，第二个参数为需要获得的信息类型的枚举值
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);

    // 将第二个参数转为int32类型便于比较
    int32\_t infoTypeParam = 0;
    OH\_JSVM\_GetValueInt32(env, args\[1\], &infoTypeParam);
    // 定义枚举类型与ArkTS侧枚举类型infoType顺序含义一致
    enum InfoType { INFO\_TYPE, INFO\_LENGTH, INFO\_ARRAY\_BUFFER, INFO\_BYTE\_OFFSET };
    void \*data;
    JSVM\_TypedarrayType type;
    size\_t byteOffset = 0;
    size\_t length = 0;
    JSVM\_Value arrayBuffer = nullptr;
    // 调用接口OH\_JSVM\_GetTypedarrayInfo获得TypedArray类型数据的信息
    JSVM\_Status status = OH\_JSVM\_GetTypedarrayInfo(env, args\[0\], &type, &length, &data, &arrayBuffer, &byteOffset);
    JSVM\_Value result = nullptr;
    // 根据属性名，返回TypedArray对应的属性值
    switch (infoTypeParam) {
        case INFO\_TYPE:
            // 如果传入的参数是int8类型的TypedArray数据，它的类型（type）为JSVM\_INT8\_ARRAY
            JSVM\_Value int8\_type;
            OH\_JSVM\_GetBoolean(env, type == JSVM\_INT8\_ARRAY, &int8\_type);
            result = int8\_type;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM GetTypedArrayInfo fail");
            } else {
                OH\_LOG\_INFO(
                    LOG\_APP, "JSVM GetTypedArrayInfo success, JSVM\_INT8\_ARRAY: %{public}d", type == JSVM\_INT8\_ARRAY);
            }
            break;
        case INFO\_LENGTH:
            // TypedArray中的元素数
            JSVM\_Value jsvmLength;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, length, &jsvmLength));
            result = jsvmLength;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM GetTypedArrayInfo fail");
            } else {
                OH\_LOG\_INFO(LOG\_APP, "JSVM GetTypedArrayInfo success, length: %{public}d", length);
            }
            break;
        case INFO\_BYTE\_OFFSET:
            // TypedArray数组的第一个元素所在的基础原生数组中的字节偏移量
            JSVM\_Value jsvmOffset;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, byteOffset, &jsvmOffset));
            result = jsvmOffset;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM GetTypedArrayInfo fail");
            } else {
                OH\_LOG\_INFO(LOG\_APP, "JSVM GetTypedArrayInfo success, byteOffset: %{public}d", byteOffset);
            }
            break;
        case INFO\_ARRAY\_BUFFER:
            {
                // TypedArray下的ArrayBuffer
                bool isArrayBuffer = false;
                JSVM\_CALL(OH\_JSVM\_IsArraybuffer(env, arrayBuffer, &isArrayBuffer));
                JSVM\_Value isArray;
                OH\_JSVM\_GetBoolean(env, isArrayBuffer, &isArray);
                result = isArray;
                if (status != JSVM\_OK) {
                    OH\_LOG\_ERROR(LOG\_APP, "JSVM GetTypedArrayInfo fail");
                } else {
                    OH\_LOG\_INFO(LOG\_APP, "JSVM GetTypedArrayInfo success, isArrayBuffer: %{public}d", isArrayBuffer);
                }
                break;
            }
        default:
            break;
    }
    return result;
}
// GetTypedArrayInfo注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetTypedArrayInfo},
};
static JSVM\_CallbackStruct \*method = param;
// GetTypedArrayInfo方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getTypedArrayInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
// is JSVM\_INT8\_ARRAY
getTypedArrayInfo(new Int8Array(3), 0);
// length
getTypedArrayInfo(new Int8Array(5), 1);
// is\_arraybuffer
getTypedArrayInfo(new Int8Array(5), 2);
// byteoffset
getTypedArrayInfo(new Int8Array(1), 3);
)JS";

预计的输出结果：

JSVM GetTypedArrayInfo success, JSVM\_INT8\_ARRAY: 1
JSVM GetTypedArrayInfo success, length: 5
JSVM GetTypedArrayInfo success, isArrayBuffer: 1
JSVM GetTypedArrayInfo success, byteOffset: 0

#### \[h2\]OH\_JSVM\_GetDataviewInfo

获取 Dataview 对象的信息。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_GetDataviewInfo的样例方法
static JSVM\_Value GetDataViewInfo(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 获取并解析参数，第一个参数为需要获得的信息的DataView类型数据，第二个参数为需要获得的信息类型的枚举值
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 将第二个参数转为int32类型的数字
    int32\_t infoType = 0;
    OH\_JSVM\_GetValueInt32(env, args\[1\], &infoType);
    size\_t byteLength = 0;
    void \*data;
    JSVM\_Value arrayBuffer = nullptr;
    size\_t byteOffset = 0;
    // 定义枚举类型与ArkTS侧枚举类型infoType顺序含义一致
    enum infoTypeEnum { BYTE\_LENGTH, ARRAY\_BUFFER, BYTE\_OFFSET };
    // 获取dataview信息
    JSVM\_Status status = OH\_JSVM\_GetDataviewInfo(env, args\[0\], &byteLength, &data, &arrayBuffer, &byteOffset);
    JSVM\_Value result = nullptr;
    switch (infoType) {
        case BYTE\_LENGTH:
            // 返回查询DataView的长度
            JSVM\_Value len;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, byteLength, &len));
            result = len;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM GetDataViewInfo fail");
            } else {
                OH\_LOG\_INFO(LOG\_APP, "JSVM GetDataViewInfo success, byteLength: %{public}d", byteLength);
            }
            break;
        case ARRAY\_BUFFER:
            {
                // 判断DataView的Info里的arraybuffer是否为arraybuffer
                bool isArrayBuffer = false;
                JSVM\_CALL(OH\_JSVM\_IsArraybuffer(env, arrayBuffer, &isArrayBuffer));
                JSVM\_Value isArray;
                OH\_JSVM\_GetBoolean(env, isArrayBuffer, &isArray);
                result = isArray;
                if (status != JSVM\_OK) {
                    OH\_LOG\_ERROR(LOG\_APP, "JSVM GetDataViewInfo fail");
                } else {
                    OH\_LOG\_INFO(LOG\_APP, "JSVM GetDataViewInfo success, isArrayBuffer: %{public}d", isArrayBuffer);
                }
                break;
            }
        case BYTE\_OFFSET:
            // 返回查询DataView的偏移量
            JSVM\_Value offset;
            JSVM\_CALL(OH\_JSVM\_CreateInt32(env, byteOffset, &offset));
            result = offset;
            if (status != JSVM\_OK) {
                OH\_LOG\_ERROR(LOG\_APP, "JSVM GetDataViewInfo fail");
            } else {
                OH\_LOG\_INFO(LOG\_APP, "JSVM GetDataViewInfo success, byteOffset: %{public}d", byteOffset);
            }
            break;
        default:
            break;
    }
    return result;
}
// GetDataViewInfo注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetDataViewInfo},
};
static JSVM\_CallbackStruct \*method = param;
// GetDataViewInfo方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getDataViewInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
// bytelength
getDataViewInfo(new DataView(new Int8Array(\[2,5\]).buffer), 0);
// is arraybuffer
let data = 'a';
let isarraybuffer = 1;
getDataViewInfo(data, isarraybuffer);
// is arraybuffer
data = new DataView(new Int8Array(\[2,5,3\]).buffer);
isarraybuffer = 1;
getDataViewInfo(data, isarraybuffer);
// byte\_offset
data = new DataView(new Int8Array(\[2,5,3\]).buffer);
isarraybuffer = 2;
getDataViewInfo(data, isarraybuffer);
)JS";

预计的输出结果：

JSVM GetDataViewInfo success, byteLength: 2
JSVM GetDataViewInfo fail
JSVM GetDataViewInfo success, isArrayBuffer: 1
JSVM GetDataViewInfo success, byteOffset: 0

#### \[h2\]OH\_JSVM\_IsArray

判断一个 JavaScript 对象是否为 Array 类型对象。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_IsArray的样例方法
static JSVM\_Value IsArray(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    bool result = false;
    JSVM\_Status status = OH\_JSVM\_IsArray(env, args\[0\], &result);
    JSVM\_Value returnValue = nullptr;
    JSVM\_CALL(OH\_JSVM\_GetBoolean(env, result, &returnValue));
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM IsArray fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsArray success, IsArray: %{public}d", result);
    }
    return returnValue;
}
// IsArray注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = IsArray},
};
static JSVM\_CallbackStruct \*method = param;
// IsArray方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"isArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let data = \[1, 2, 3, 4, 5\];
isArray(data);
)JS";

预计的输出结果：

JSVM IsArray success, IsArray: 1

#### \[h2\]OH\_JSVM\_SetElement

在给定对象的指定索引处设置元素。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_SetElement的样例方法
static int DIFF\_VALUE\_THREE = 3;
static JSVM\_Value SetElement(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = DIFF\_VALUE\_THREE;
    JSVM\_Value args\[3\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    int32\_t index = 0;
    OH\_JSVM\_GetValueInt32(env, args\[1\], &index);
    JSVM\_Status status = OH\_JSVM\_SetElement(env, args\[0\], index, args\[2\]);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM SetElement fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM SetElement success");
    }
    return args\[0\];
}
// SetElement注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = SetElement},
};
static JSVM\_CallbackStruct \*method = param;
// SetElement方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"setElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let data = \[1, 2, 3, 4, 5\];
setElement(data, 3, undefined);
)JS";

预计的输出结果：

JSVM SetElement success

#### \[h2\]OH\_JSVM\_GetElement

获取给定对象指定索引处的元素。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_GetElement的样例方法
static JSVM\_Value GetElement(JSVM\_Env env, JSVM\_CallbackInfo info) {
    // 获取js侧传入的两个参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 获取请求元素的索引值
    uint32\_t index = 0;
    OH\_JSVM\_GetValueUint32(env, args\[1\], &index);
    // 获取请求索引位置的元素值并存储在result中
    JSVM\_Value result = nullptr;
    JSVM\_Status status = OH\_JSVM\_GetElement(env, args\[0\], index, &result);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetElement fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetElement success");
    }
    return result;
}
// GetElement注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetElement},
};
static JSVM\_CallbackStruct \*method = param;
// GetElement方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let arr = \[10, 'hello', null, true\];
getElement(arr, 3);
)JS";

预计的输出结果：

JSVM GetElement success

#### \[h2\]OH\_JSVM\_HasElement

若给定对象的指定索引处拥有属性，获取元素。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_HasElement的样例方法
static JSVM\_Value HasElement(JSVM\_Env env, JSVM\_CallbackInfo info) {
    // 获取js侧传入的两个参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 获取要判断的元素的索引
    uint32\_t index = 0;
    OH\_JSVM\_GetValueUint32(env, args\[1\], &index);
    // 判断指定索引位置的元素是否存在
    bool hasElement = true;
    JSVM\_Status status = OH\_JSVM\_HasElement(env, args\[0\], index, &hasElement);
    // 将boolean结果转换为JSVM\_Value并返回
    JSVM\_Value result = nullptr;
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM hasElement fail");
    } else {
        OH\_JSVM\_GetBoolean(env, hasElement, &result);
        OH\_LOG\_INFO(LOG\_APP, "JSVM hasElement: %{public}d", hasElement);
    }
    return result;
}
// HasElement注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = HasElement},
};
static JSVM\_CallbackStruct \*method = param;
// HasElement方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"hasElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let arr = \[10, 'hello', null, true\];
hasElement(arr, 0);
hasElement(arr, 4);
)JS";

预计的输出结果：

JSVM hasElement: 1
JSVM hasElement: 0

#### \[h2\]OH\_JSVM\_DeleteElement

尝试删除给定对象的指定索引处的元素。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_DeleteElement的样例方法
static JSVM\_Value DeleteElement(JSVM\_Env env, JSVM\_CallbackInfo info) {
    // 获取js侧传入的两个参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    JSVM\_CALL(OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr));
    // 获取要删除的元素的索引
    uint32\_t index = 0;
    JSVM\_CALL(OH\_JSVM\_GetValueUint32(env, args\[1\], &index));
    // 尝试删除请求索引位置的元素
    bool deleted = true;
    JSVM\_Status status = OH\_JSVM\_DeleteElement(env, args\[0\], index, &deleted);
    // 将boolean结果转换为JSVM\_Value并返回
    JSVM\_Value result = nullptr;
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM DeleteElement fail");
    } else {
        OH\_JSVM\_GetBoolean(env, deleted, &result);
        OH\_LOG\_INFO(LOG\_APP, "JSVM DeleteElement: %{public}d", deleted);
    }
    return result;
}
// DeleteElement注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = DeleteElement},
};
static JSVM\_CallbackStruct \*method = param;
// DeleteElement方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"deleteElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let arr = \[10, 'hello', null, true\];
deleteElement(arr, 0);
)JS";

预计的输出结果：

JSVM DeleteElement: 1

#### \[h2\]OH\_JSVM\_IsDataview

判断一个 JavaScript 对象是否为 Dataview 类型对象。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_IsDataview的样例方法
static JSVM\_Value IsDataView(JSVM\_Env env, JSVM\_CallbackInfo info) {
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 调用OH\_JSVM\_IsDataview接口判断给定入参是否为DataView数据。
    bool result = false;
    JSVM\_Status status = OH\_JSVM\_IsDataview(env, args\[0\], &result);
    JSVM\_Value isDataView = nullptr;
    OH\_JSVM\_GetBoolean(env, result, &isDataView);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM IsDataView fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsDataView: %{public}d", result);
    }
    return isDataView;
}
// IsDataView注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = IsDataView},
};
static JSVM\_CallbackStruct \*method = param;
// IsDataView方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"isDataView", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
let buffer = new ArrayBuffer(16);
let dataView = new DataView(buffer);
isDataView(dataView);
)JS";

预计的输出结果：

JSVM IsDataView: 1

#### \[h2\]OH\_JSVM\_IsTypedarray

判断一个 JavaScript 对象是否为 TypedArray 类型对象。

cpp 部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_IsTypedarray的样例方法
static JSVM\_Value IsTypedarray(JSVM\_Env env, JSVM\_CallbackInfo info) {
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    bool result = false;
    JSVM\_Status status = OH\_JSVM\_IsTypedarray(env, args\[0\], &result);
    JSVM\_Value isTypedArray = nullptr;
    OH\_JSVM\_GetBoolean(env, result, &isTypedArray);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM IsTypedarray fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsTypedarray: %{public}d", result);
    }
    return isTypedArray;
}
// IsTypedarray注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = IsTypedarray},
};
static JSVM\_CallbackStruct \*method = param;
// IsTypedarray方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"isTypedarray", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char \*srcCallNative = R"JS(
isTypedarray(new Uint16Array(\[1, 2, 3, 4\]));
)JS";

预计的输出结果：

JSVM IsTypedarray: 1