类型化数组与常规数组的相似点

类型化数组与常规数组有好几个相似点,并且正如你已经在本章看到的那样, 类型化数组在很多场景中都可以像常规数组那样被使用。例如,你可以使用 length 属性来获取类型化数组包含的元素数量,还可以使用数值类型的索引值来直接访问类型化数组的元素。举个例子:

let ints = new Int16Array([25, 50]);

console.log(ints.length);          // 2
console.log(ints[0]);              // 25
console.log(ints[1]);              // 50

ints[0] = 1;
ints[1] = 2;

console.log(ints[0]);              // 1
console.log(ints[1]);              // 2

这段代码创建了一个包含两个元素的 Int16Array,使用数值类型的索引可以读写对应的项,而数值在存储时会被自动转换为 int16 类型的值。

相似点还不限于此。

与常规数组不同的是,你不能使用 length 属性来改变类型化数组的大小。该属性是不可写的,在非严格模式下写入操作会被忽略,而严格模式下则会抛出错误。

公共方法

类型化数组也拥有大量与常规数组等效的方法,你可以对类型化数组使用下列这些方法:

  • copyWithin()

  • entries()

  • fill()

  • filter()

  • find()

  • findIndex()

  • forEach()

  • indexOf()

  • join()

  • keys()

  • lastIndexOf()

  • map()

  • reduce()

  • reduceRight()

  • reverse()

  • slice()

  • some()

  • sort()

  • values()

注意:虽然这些方法的表现与数组原型上的对应方法相似,但它们并不完全相同。类型化数组的方法会进行额外的类型检查以确保安全,并且返回值会是某种类型化数组,而不是常规数组(归结于 Symbol.species 属性)。这里有个例子用于演示其中的区别:

let ints = new Int16Array([25, 50]),
    mapped = ints.map(v => v * 2);

console.log(mapped.length);        // 2
console.log(mapped[0]);            // 50
console.log(mapped[1]);            // 100

console.log(mapped instanceof Int16Array);  // true

这段代码通过 map() 方法使用 ints 中的值创建了一个新数组,映射函数将每个值翻倍,并返回了一个新的 Int16Array 。

相同的迭代器

与常规数组相同,类型化数组也拥有三个迭代器,它们是 entries() 方法、keys() 方法与 values() 方法。这就意味着你可以对类型化数组使用扩展运算符,或者对其使用 for-of 循环,就像对待常规数组。举个例子:

let ints = new Int16Array([25, 50]),
    intsArray = [...ints];

console.log(intsArray instanceof Array);    // true
console.log(intsArray[0]);                  // 25
console.log(intsArray[1]);                  // 50

此代码创建了一个名为 intsArray 的新数组,包含了类型化数组 ints 的所有数据。借助扩展运算符能轻易地将类型化数组转换为常规数组,就像处理其他可迭代对象那样。

of() 与 from() 方法

最后,所有的类型化数组都包含静态的 of() 与 from() 方法,作用类似于 Array.of() 与 Array.from() 方法。其中的区别是类型化数组的版本会返回类型化数组,而不返回常规数组。下面的例子使用这两个方法创建了几个类型化数组:

let ints = Int16Array.of(25, 50),
    floats = Float32Array.from([1.5, 2.5]);

console.log(ints instanceof Int16Array);        // true
console.log(floats instanceof Float32Array);    // true

console.log(ints.length);       // 2
console.log(ints[0]);           // 25
console.log(ints[1]);           // 50

console.log(floats.length);     // 2
console.log(floats[0]);         // 1.5
console.log(floats[1]);         // 2.5

此例中分别使用了 of() 与 from() 方法来创建一个 Int16Array 以及一个 Float32Array,这两个方法确保创建类型化数组能像创建常规数组那样轻松。