从ECMA规范到ArkTS接口(一)--typedArray.slice接口 原创

深开鸿
发布于 2024-4-2 09:49
浏览
1收藏

作者:王清
在深入理解和使用ArkTS中的数组操作之前,我们有必要先了解ECMAScript(ECMA)规范中的规定。ECMA规范是JavaScript语言的官方标准,而ArkTS作为JavaScript的超集,也遵守了这些规定。本系列文章旨在探讨ECMA规范如何定义接口,以及如何在ArkTS该接口如何使用。

ECMA介绍

ECMAScript是由Ecma国际(前身为欧洲计算机制造商协会ECMA)制定的语言标准,目标是标准化JavaScript语言。JavaScript通常用于网页和服务器端编程,而ECMAScript则为这些使用情境提供了一套规范。

ECMAScript(ES)的标准自2015年以来进入了年度发布周期,意味着每年都会发布一个新版本。这个变化始于ECMAScript 6(ES6)或ECMAScript 2015的发布,之后的每个版本通常被称为ECMAScript 2016(ES7)、ECMAScript 2017(ES8)、以此类推,直到最新的版本。

这种年度发布计划允许JavaScript语言以小的、可管理的步骤来引入新特性,使得开发者更容易跟上语言的变化,同时也使得浏览器和环境开发者更容易实现和支持新标准。每个版本的新特性通常在年初被确定,并在年中的ECMA General Assembly会议上正式批准。

截至本文发布,当前最新版本为ECMAScript 2023,也称为ES14。

ECMA对typedArray.slice接口的定义

在ECMA规范中,typedArray 是一个泛型对象,表示一个固定长度的二进制数据缓冲区,并且可以用来创建多种类型的视图,比如 Uint8ArrayInt16ArrayFloat32Array 等。而其中的 .slice() 方法,用于浅复制 typedArray 的一部分到一个新的 typedArray 实例。

根据ECMAScript规范,typedArray.slice(begin, end) 方法接受两个参数:begin 表示起始位置,end 表示结束位置(不包含)。如果不提供 end 参数,slice 方法会复制从 begin 到原数组末尾的所有元素。如果 beginend 是负数,则表示从数组末尾开始的偏移量。返回值是一个新的 typedArray 实例,包含指定范围的元素。

我们可以直接查看ECMA规范中对该函数的描述:

23.2.3.27 %TypedArray%.prototype.slice ( start, end )
The interpretation and use of the arguments of this method are the same as for Array.prototype.slice as defined in 23.1.3.28.

This method performs the following steps when called:
1. Let O be the this value.
2. Perform ? ValidateTypedArray(O).
3. Let len be O.[[ArrayLength]].
4. Let relativeStart be ? ToIntegerOrInfinity(start).
5. If relativeStart = -∞, let k be 0.
6. Else if relativeStart < 0, let k be max(len + relativeStart, 0).
7. Else, let k be min(relativeStart, len).
8. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
9. If relativeEnd = -∞, let final be 0.
10. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
11. Else, let final be min(relativeEnd, len).
12. Let count be max(final - k, 0).
13. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(count) »).
14. If count > 0, then
    a. If IsDetachedBuffer(O.[[ViewedArrayBuffer]]) is true, throw a TypeError exception.
    b. Let srcType be TypedArrayElementType(O).
    c. Let targetType be TypedArrayElementType(A).
    d. If srcType is targetType, then
        i. NOTE: The transfer must be performed in a manner that preserves the bit-level encoding of the source data.
        ii. Let srcBuffer be O.[[ViewedArrayBuffer]].
        iii. Let targetBuffer be A.[[ViewedArrayBuffer]].
        iv. Let elementSize be TypedArrayElementSize(O).
        v. Let srcByteOffset be O.[[ByteOffset]].
        vi. Let srcByteIndex be (k × elementSize) + srcByteOffset.
        vii. Let targetByteIndex be A.[[ByteOffset]].
        viii. Let limit be targetByteIndex + count × elementSize.
        ix. Repeat, while targetByteIndex < limit,
            1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, Uint8, true, Unordered).
            2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, Uint8, value, true, Unordered).
            3. Set srcByteIndex to srcByteIndex + 1.
            4. Set targetByteIndex to targetByteIndex + 1.
	e. Else,
        i. Let n be 0.
        ii. Repeat, while k < final,
            1.Let Pk be ! ToString(𝔽(k)).
            2.Let kValue be ! Get(O, Pk).
            3.Perform ! Set(A, ! ToString(𝔽(n)), kValue, true).
            4.Set k to k + 1.
            5.Set n to n + 1.
15. Return A.
This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.

大家可以看到,ECMA规范中对接口的描述非常详细,对各种参数的输入和输出都做非常细致的说明,无论是符合标准的语言接口的实现,还是

ArkTS对slice的接口描述

在ArkTS中,接口(Interfaces)是一个非常强大的特性,允许开发者定义对象的类型。为了实现一个符合ECMA规范的 slice 方法,ArkTS对该方法的定义声明如下:

以\static_core\plugins\ets\stdlib\escompat\TypedUArrays.ets的Uint8Array定义为例:

/**
     * Creates a slice of current Uint8Array using range [begin, end)
     *
     * @param begin start index to be taken into slice
     *
     * @param end last index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin;end) where end index is excluded
     *
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
     */
    public slice(begin?: Number, end?: Number): Uint8Array {
        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
    }

    /**
     * Creates a slice of current Uint8Array using range [begin, end)
     *
     * @param begin start index to be taken into slice
     *
     * @param end last index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin;end) where end index is excluded
     *
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
     */
    public slice(begin: number, end: number): Uint8Array {
        return this.slice(begin as int, end as int)
    }

    /**
     * Creates a slice of current Uint8Array using range [begin, end)
     *
     * @param begin start index to be taken into slice
     *
     * @param end last index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin;end) where end index is excluded
     *
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
     */
    public slice(begin: number, end: int): Uint8Array {
        return this.slice(begin as int, end as int)
    }

    /**
     * Creates a slice of current Uint8Array using range [begin, end)
     *
     * @param begin start index to be taken into slice
     *
     * @param end last index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin;end) where end index is excluded
     *
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
     */
    public slice(begin: int, end: number): Uint8Array {
        return this.slice(begin as int, end as int)
    }

    /**
     * Creates a slice of current Uint8Array using range [begin, end)
     *
     * @param begin start index to be taken into slice
     *
     * @param end last index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin;end) where end index is excluded
     *
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
     */
    public slice(begin: int, end: int): Uint8Array {
        const len: int = this.lengthInt
        const relStart = normalizeIndex(begin, len)
        const relEnd = normalizeIndex(end, len)
        let count = relEnd - relStart
        if (count < 0) {
            count = 0
        }
        if (this.buffer instanceof ArrayBuffer) {
            let buf = (this.buffer as ArrayBuffer).slice(relStart * Uint8Array.BYTES_PER_ELEMENT as int, relEnd * Uint8Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
            return new Uint8Array(buf)
        } else if (this.buffer instanceof SharedArrayBuffer) {
            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Uint8Array.BYTES_PER_ELEMENT as int, relEnd * Uint8Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
            return new Uint8Array(buf)
        } else {
            throw new Error("unexpected type of buffer")
        }
    }

    /**
     * Creates a slice of current Uint8Array using range [begin, this.lengthInt).
     *
     * @param begin start index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin, this.lengthInt)
     */
    public slice(begin: number): Uint8Array {
        return this.slice(begin as int)
    }

    /**
     * Creates a slice of current Uint8Array using range [begin, this.lengthInt).
     *
     * @param begin start index to be taken into slice
     *
     * @returns a new Uint8Array with elements of current Uint8Array[begin, this.lengthInt)
     */
    public slice(begin: int): Uint8Array {
        return this.slice(begin, this.lengthInt)
    }

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.

在这个例子中,我们创建了一个 Int32ArrayWithSlice 类,它实现了 TypedArray 接口,包含了符合ECMA规范的 slice 方法。这个方法返回的是 Int32ArrayWithSlice 的新实例,包含了切片后的元素。

测试用例

要验证我们的 slice 方法实现是否正确,我们可以编写单元测试用例。这里我们使用了ArkTS和Jest测试框架,来确保我们的实现与ECMA规范一致。

const success = 0;
const fail = 1;
function testSliceWithOutParam(): int {
  let source: number[] = [10, 20, 30, 40, 50, 60];
  let ss = new ArrayBuffer(source.length as int * 1);

  let origin: Uint8Array;

  try {
    origin = new Uint8Array(ss);
    origin.set(source);
  } catch(e) {
    console.log(e);
    return fail;
  }


  let target: Uint8Array;

  try {
    target = origin.slice();
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != origin.length as int) {
    console.log("Array length mismatch on slice");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = 0; i< origin.length as int; i++) {
    let tv = target[i] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  origin= new Uint8Array(0);
  if(origin.length as int != 0){
    return fail;
  }

  try {
    target = origin.slice();
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != 0){
    return fail;
  }
  return success;
}

function testSliceOneParam(): int {
  let source: number[] = [10, 20, 30, 40, 50, 60];
  let ss = new ArrayBuffer(source.length as int * 1);

  let origin: Uint8Array;

  try {
    origin = new Uint8Array(ss);
    origin.set(source);
  } catch(e) {
    console.log(e);
    return fail;
  }

  let sliceStart: int = 1;
  let sliceEnd: int = origin.length as int;

  let target: Uint8Array;

  try {
    target = origin.slice(sliceStart);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != origin.length as int - sliceStart) {
    console.log("Array length mismatch on slice One Params" + target.length);
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  sliceStart = 0;
  try {
    target = origin.slice(undefined);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != origin.length as int) {
    console.log("Array length mismatch on slice One Params" + target.length);
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  return success;
}

function testSliceTwoParams(): int {
  let source: number[] = [10, 20, 30, 40, 50, 60, 70, 80];
  let ss = new ArrayBuffer(source.length as int * 1);

  let origin: Uint8Array;

  try {
    origin = new Uint8Array(ss);
    origin.set(source);
  } catch(e) {
    console.log(e);
    return fail;
  }

  let sliceStart: int = 2;
  let sliceEnd: int = 4;

  let target: Uint8Array;

  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != sliceEnd - sliceStart) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  sliceStart = 0;
  sliceEnd = origin.length as int;
  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != sliceEnd - sliceStart) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  try {
    target = origin.slice(new Number(sliceStart), undefined);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != sliceEnd - sliceStart) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  try {
    target = origin.slice(undefined, undefined);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != sliceEnd - sliceStart) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  try {
    target = origin.slice(undefined, new Number(sliceEnd));
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != sliceEnd - sliceStart) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = sliceStart; i< sliceEnd; i++) {
    let tv = target[i - sliceStart] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  try {
    target = origin.slice(0, 0);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != 0) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  return success;
}

function testSliceTwoParamsWithOtherNumber(): int {
  let source: number[] = [10, 20, 30, 40, 50, 60, 70, 80];
  let ss = new ArrayBuffer(source.length as int * 1);

  let origin: Uint8Array;

  try {
    origin = new Uint8Array(ss);
    origin.set(source);
  } catch(e) {
    console.log(e);
    return fail;
  }

  let sliceStart: int = 4;
  let sliceEnd: int = 2;

  let target: Uint8Array;

  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    return fail;
  }

  if(target.length as int != 0) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  sliceStart = -1;
  sliceEnd = origin.length as int;
  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    return fail;
  }

  if(target.length as int != sliceEnd - (origin.length + sliceStart)) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  //Check all the data copied;
  for(let i:int = (origin.length + sliceStart) as int; i< sliceEnd; i++) {
    let tv = target[i - (origin.length + sliceStart)] as number;
    let ov = origin[i] as number;
    console.log(source[i] + "->" + tv + "->" + ov);
    if(tv != ov) {
      console.log("Array data mismatch");
      return fail;
    }
  }

  sliceStart = 0;
  sliceEnd = -origin.length as int;
  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    console.log(e);
    return fail;
  }

  if(target.length as int != (origin.length + sliceEnd) - sliceStart) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  return success;
}

function testSliceOneLengthTwoParams(): int {
  let source: number[] = [10];
  let ss = new ArrayBuffer(source.length as int * 1);

  let origin: Uint8Array;

  try {
    origin = new Uint8Array(ss);
    origin.set(source);
  } catch(e) {
    console.log(e);
    return fail;
  }
  
  let sliceStart: int = 4;
  let sliceEnd: int = 2;

  let target: Uint8Array;

  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    return fail;
  }

  if(target.length as int != 0) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  sliceStart = 2;
  sliceEnd = 4;
  try {
    target = origin.slice(sliceStart, sliceEnd);
  } catch(e) {
    return fail;
  }

  if(target.length as int != 0) {
    console.log("Array length mismatch on slice2");
    return fail;
  }

  return success;
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.
  • 340.
  • 341.
  • 342.
  • 343.
  • 344.
  • 345.
  • 346.
  • 347.
  • 348.
  • 349.
  • 350.
  • 351.
  • 352.
  • 353.
  • 354.
  • 355.
  • 356.
  • 357.
  • 358.
  • 359.
  • 360.
  • 361.
  • 362.
  • 363.
  • 364.
  • 365.
  • 366.
  • 367.
  • 368.
  • 369.
  • 370.
  • 371.
  • 372.
  • 373.
  • 374.
  • 375.
  • 376.
  • 377.
  • 378.
  • 379.
  • 380.
  • 381.
  • 382.
  • 383.
  • 384.
  • 385.
  • 386.
  • 387.
  • 388.
  • 389.
  • 390.
  • 391.
  • 392.
  • 393.
  • 394.
  • 395.
  • 396.
  • 397.

这些测试用例检查了 slice 方法在正常条件下和非正常条件下的行为。通过运行这些测试,我们可以确认我们的实现是否符合接口定义预期和ECMA规范。

总结来说,理解ECMA规范中的接口是任何ArkTS开发者的基本功,而且通过单元测试可以保证实现的准确性和可靠性。通过逐步实现这些接口并验证它们的行为,我们可以确保我们的ArkTS代码既强大又稳健。

参考文献:

  1. ECMA262-14th规范

  2. 方舟运行时公共组件

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
2
收藏 1
回复
举报
2
1
1
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

重新了解下ArkTS

回复
2024-4-2 10:03:40


回复
    相关推荐