Array.from
方法用于把两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。
下面是一个类似数组的对象,Array.from
将它转为真正的数组
let arrayLike = {"0":"a","1":"b","2":"c",length:3};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a','b','c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a','b','c']
实际应用中,常见的类似数组的对象是DOM操作返回的NodeList集合,以及函数内部的arguments
对象,Array.from
都可以把它们转为真正的数组。
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function(p){
console.log(p);
});
// arguments对象
function foo(){
var args = Array.from(arguments);
// ...
}
上面的代码中,querySelectorAll
方法返回的是一个类似数组的对象,只有讲这个对象转为真正的数组,才能使用forEach
方法。
只要是部署了Iterator接口的数据结构,Array.from
都能将其转为数组
Array.from('hello');
// ['h','e','l','l','o']
let nameSet = new Set(['a','b']);
Array.from(nameSet) // ['a','b']
上面的代码中,字符串和Set结构都具有Iterator接口,因此可以被Array.from
转为真正的数组。
所谓类似数组的对象,本质特征只有一点,即必须有length
属性。因此,任何有length
属性的对象,都可以通过Array.from
方法转为数组
Array.from({length:3});
// [undefined,undefined,undefined]
对于还没有部署该方法的浏览器,可以用Array.prototype.slice
方法替代
const toArray = (()=>Array.from ? Array.from : obj=>[].slice.call(obj))();
Array.from
还可以接受第二个参数,作用类似于数组的map
方法,用来对每个元素进行处理,讲处理后的值放入返回的数组
Array.from(arrayLike, x=>x*x);
// 等同于
Array.from(arrayLike).map(x=>x*x);
Array.from([1,2,3], (x)=>x*x)
// [1,4,9]
Array.from()
的另一个应用是,将字符串转为数组,然后返回字符串的长度。因为它能够处理各种Unicode字符,可以避免JavaScript将大于\uFFFF
的Unicode字符,算作是两个字符的bug
function countSymbols(string){
return Array.from(string).length;
}