ZetCode

JavaScript 子数组方法

最后修改于 2025 年 4 月 4 日

在本文中,我们将展示如何使用 JavaScript 中的 subarray 方法提取数组的部分。

数组提取

数组提取是从现有数组的一部分创建一个新数组的操作。subarray 方法与类型化数组一起使用,用于在同一个 ArrayBuffer 上返回一个新的类型化数组。

当您需要使用数组元素的子集而无需修改原始数组时,此方法很有用。subarray 与原始数组共享相同的内存。

subarray 方法接受开始和结束索引参数。返回的数组包含从开始索引到但不包括结束索引的元素。负索引从数组的末尾开始计数。

基本子数组示例

以下示例演示了 subarray 方法与类型化数组的基本用法。

main.js
const buffer = new ArrayBuffer(8);
const arr = new Int8Array(buffer);
arr.set([10, 20, 30, 40, 50, 60, 70, 80]);

const sub = arr.subarray(2, 5);

console.log('Original:', arr);
console.log('Subarray:', sub);

我们创建一个 Int8Array,并提取从索引 2 到 4(不包括 5)的元素。子数组与原始数组共享相同的缓冲区。对一个数组的更改将影响另一个数组。

$ node main.js
Original: Int8Array(8) [
  10, 20, 30, 40,
  50, 60, 70, 80
]
Subarray: Int8Array(3) [ 30, 40, 50 ]

使用负索引

subarray 方法接受从数组末尾开始计数的负索引。

main.js
const buffer = new ArrayBuffer(12);
const arr = new Uint16Array(buffer);
arr.set([100, 200, 300, 400, 500, 600]);

const sub = arr.subarray(-4, -1);

console.log('Original:', arr);
console.log('Subarray:', sub);

我们创建一个 Uint16Array,并使用负索引提取元素。 -4 指的是从末尾开始的第 4 个元素,-1 指的是最后一个元素(不包括)。

$ node main.js
Original: Uint16Array(6) [ 100, 200, 300, 400, 500, 600 ]
Subarray: Uint16Array(3) [ 300, 400, 500 ]

省略结束索引

当省略结束索引时,子数组将提取到数组的末尾。

main.js
const buffer = new ArrayBuffer(10);
const arr = new Int32Array(buffer);
arr.set([1, 2, 3, 4, 5]);

const sub = arr.subarray(2);

console.log('Original:', arr);
console.log('Subarray:', sub);

我们创建一个 Int32Array,并提取从索引 2 到末尾的元素。子数组包含从开始索引到数组末尾的所有元素。

$ node main.js
Original: Int32Array(5) [ 1, 2, 3, 4, 5 ]
Subarray: Int32Array(3) [ 3, 4, 5 ]

共享缓冲区行为

子数组与原始数组共享相同的缓冲区,因此更改在两者中都可见。

main.js
const buffer = new ArrayBuffer(16);
const arr = new Float64Array(buffer);
arr.set([1.1, 2.2, 3.3, 4.4]);

const sub = arr.subarray(1, 3);
sub[0] = 9.9;

console.log('Original:', arr);
console.log('Subarray:', sub);

我们演示了修改子数组会影响原始数组。这两个数组共享相同的底层缓冲区。这与创建副本的 slice() 不同。

$ node main.js
Original: Float64Array(4) [ 1.1, 9.9, 3.3, 4.4 ]
Subarray: Float64Array(2) [ 9.9, 3.3 ]

创建完整副本

要创建完全独立的副本,您可以将 subarray 与 slice 结合使用。

main.js
const buffer = new ArrayBuffer(8);
const arr = new Uint8Array(buffer);
arr.set([10, 20, 30, 40, 50, 60, 70, 80]);

const copy = new Uint8Array(arr.subarray(2, 6).buffer.slice(0));

console.log('Original:', arr);
console.log('Copy:', copy);

copy[0] = 99;
console.log('After modification:');
console.log('Original:', arr);
console.log('Copy:', copy);

我们创建一个真正的副本,它不与原始数组共享内存。修改副本不会影响原始数组。此技术为副本创建了一个新的缓冲区。

$ node main.js
Original: Uint8Array(8) [
  10, 20, 30, 40,
  50, 60, 70, 80
]
Copy: Uint8Array(4) [ 30, 40, 50, 60 ]
After modification:
Original: Uint8Array(8) [
  10, 20, 30, 40,
  50, 60, 70, 80
]
Copy: Uint8Array(4) [ 99, 40, 50, 60 ]

来源

TypedArray 子数组 - 语言参考

在本文中,我们已经演示了如何使用 subarray() 方法从 JavaScript 中提取类型化数组的部分。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出 所有 JS 数组函数。