ES6数组扩展方法详解:from、of与copyWithin

作者:小括号

时间:2026-10-30

浏览:303

本文深入解析ES6中数组的三大扩展方法:Array.from用于将类数组或可迭代对象转为真正的数组,解决DOM集合无法直接使用数组方法的问题;Array.of弥补构造函数在单参数时的长度歧义,确保参数始终视为元素;copyWithin实现数组内部数据的原地复制与替换。通过具体代码示例,展示各方法在不同数据类型下的行为差异及实际应用场景。

文章目录

Array.from:类数组转真数组

将类数组结构转换为真正的数组对象。

首先介绍应用场景。在JavaScript开发中,操作DOM节点是常见需求。例如,获取页面上所有的input标签,筛选出类型为button的元素,并为其绑定点击事件。传统的实现方式可能如下所示:


var inputObjs=document.getElementsByTagName('input');
for(var i=0;i<inputObjs.length;i++){
if(inputObjs[i].type==='button'){
inputObjs[i].onclick=function(){
return;
}
}
}

上述写法虽然功能正确,但效率较低。我们更倾向于使用数组提供的高阶方法,如ES5引入的forEach。然而,直接调用会报错,因为DOM集合(HTMLCollection)并非真正的Array实例,不具备数组原型链上的方法。


var inputObjs=document.getElementsByTagName('input');
inputObjs.forEach(); //inputObjs.forEach is not a function

尽管不能直接调用,仍可通过对象冒充的方式间接实现。利用JavaScript强大的原型链特性,可以借用数组的方法。


var inputObjs=document.getElementsByTagName('input');
console.info(inputObjs); //[]length: 0__proto__: HTMLCollection
console.info([].slice.call(inputObjs)); //[]length: 0__proto__: Array[0]

转换完成后,即可自由调用各类数组方法。虽然此方案可行,但代码可读性较差且逻辑迂回。ES6提供了更简洁直接的解决方案:Array.from()。其使用方式如下:


var inputObjs=document.getElementsByTagName('input');
console.info(inputObjs); //[]length: 0__proto__: HTMLCollection
console.info(Array.from(inputObjs)); //[]length: 0__proto__: Array[0]

最终结果一致,但语义更清晰,易于理解。此外,Array.from()不仅适用于类数组对象,还可处理其他数据类型,但不同输入类型的转换结果各异。具体测试如下:


let str='google';
console.log(Array.from(str)); //["g", "o", "o", "g", "l", "e"]
let num=234;
console.log(Array.from(num)); //[]
let bol=false;
console.log(Array.from(bol));
let obj={foo:'foo',bar:'bar'};
console.log(Array.from(obj)); //[]
let superObj={0:'foo',1:'bar',length:2};
console.log(Array.from(superObj)); //["foo", "bar"]

上述示例展示了不同数据类型经Array.from()处理后的结果。需注意,字符串和具有数字键值对及length属性的特殊对象,可转换为包含内容的数组。这类对象支持for循环遍历,字符串也可通过循环获取字符,因此只要支持for循环输出内容的对象,使用from方法后均非空数组。对于熟悉jQuery的开发者,选择器返回的jQuery对象结构与此例中的特殊对象类似,具体可参考jQuery源码分析系列文章。

Array.of:值转数组与构造函数区别

Array.of()方法用于将一组值转换为数组。

创建数组主要有两种传统方式:构造函数法。


let arr=Array(1,2,3);

以及最常用的字面量法。


let arr=[1,2,3];

Array.of()是对构造函数法的补充,其用法示例如下:


console.log(Array.of(1,2,3)); //[1,2,3]

乍看之下,它与构造函数效果相似,但其存在必要性在于解决构造函数在单参数时的歧义问题。通过以下示例即可明了:


console.log(Array()); //[]
console.log(Array(1)); //[undefined]
console.log(Array(1,2)); //[1,2]

在此示例中,參數數量的不同其代表的意義不一樣,只有一個參數時,參數表示的是長度,大於1一個參數時表示的元素,會引起混淆,但是Array.of方法就不會存在此問題嗎,因其參數始終表示的元素:


console.log(Array.of()); //[]
console.log(Array.of(1)); //[1]
console.log(Array.of(1,2)); //[1,2]

copyWithin:数组内部数据复制

copyWithin()方法用于数组内部数据的复制与替换。

该方法接受三个参数:起始复制位置、结束复制位置和插入目标位置。示例如下:


[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]
// 将3号位复制到0号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}
// 将2号位到数组结束,复制到0号位
var i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// 对于没有部署TypedArray的copyWithin方法的平台
// 需要采用下面的写法
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]

以上介绍了ES6中数组的主要扩展方法,希望能帮助读者理解并应用。如有任何疑问,欢迎留言交流,小编将及时回复。感谢大家的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章