语法规则
const someNumbers = {'0': 10, '1': 15, length: 2};
Array.from(someNumbers, value => value * 2); // => [20, 30]
将类数组转换成数组
你会碰到的类数组对象有:函数中的 arguments 关键字,或者是一个 DOM 集合。
在下面的示例中,让我们对函数的参数求和
function sumArguments() {return Array.from(arguments).reduce((sum, num) => sum + num);
}
sumArguments(1, 2, 3); // => 6
Array.from() 的第一个参数可以是任意一个可迭代对象,我们继续看一些例子:
Array.from('Hey'); // => ['H', 'e', 'y']
Array.from(new Set(['one', 'two'])); // => ['one', 'two']
const map = new Map();
map.set('one', 1)
map.set('two', 2);
Array.from(map); // => [['one', 1], ['two', 2]]
浅拷贝数组
var arr=[
0,
[1,1,1],
[2,2,2],
[3,3,4],
]
/* var arr2 = arr
arr2[0]=-1;
arr2[1][0]=11;
console.log(arr2)对 arr2 的修改全部会影响 arr
console.log(arr)*/
var arr2 = Array.from(arr)
arr2[0]=-1;
arr2[1][0]=11;
// 对 arr2 的首层修改会不会影响 arr,嵌套还是会影响,这时我们就需要深拷贝
console.log(arr2)
console.log(arr)
构造深拷贝数组函数
可以看到这是深拷贝数组的最简单写法,可以轻松深拷贝一个数组
但存在缺陷,如果数组嵌套对象就无法深拷贝对象
function deepCloneArray(arr){if(Array.isArray(arr)){return Array.from(arr,deepCloneArray)// 递归入口
}else{return arr}
}
var arr2 = deepCloneArray(arr)
arr2[0]=-1;
arr2[1][0]=11;
arr2[2][0].name=22;
console.log(arr2)
console.log(arr)
填充数组
这里用 {length} 创了一个含有 length 属性的类数组对象,可以用来迭代
const length = 3;
const init = 0;
const result = Array.from({length}, () => init);
result; // => [0, 0, 0]
fill 函数也能快速填充,但在使用对象填充数组的时候有局限性
// 先生成 3 个空项的数组再填充
const result = Array(3).fill(0);
result ; // => [0, 0, 0]
使用对象填充数组
const length = 3;
const resultA = Array.from({length}, () => ({}));
const resultB = Array(length).fill({});
resultA; // => [{}, {}, {}]
resultB; // => [{}, {}, {}]
resultA[0] === resultA[1]; // => false
resultB[0] === resultB[1]; // => true
由 Array.from 返回的 resultA 使用不同空对象实例进行初始化。之所以发生这种情况是因为每次调用时,mapFunction,即此处的 () => ({}) 都会返回一个新的对象。
而 fill 填充的 {} 是同一个空对象,最后填充出来的对象的修改会反应到同一个堆内存中
数组快速去重
new Set(array) 创建了一个包含数组的集合,Set 集合会删除重复项。
因为 Set 集合是可迭代的,所以可以使用 Array.from() 将其转换为一个新的数组。
function unique(array) {return Array.from(new Set(array));
}
unique([1, 1, 2, 3, 3]); // => [1, 2, 3]