Array 类对象上增加了几个专有方法。
Array.from()
方法的基本功能是将下面两种类型的对象转换成数组:
-
类数组对象(Array-like objects),它具有 length 属性和索引元素,比如像
document.getElementsByClassName()
这种 DOM 操作的返回值。 -
可迭代的对象(Iterable object),它的内容可以每次被检索一个元素。数组是可迭代的,同样的 ES6 中新的数据结构,Map 和 Set 也是可迭代的。
下面的代码是将类数组对象(Array-like objects)转换成数组:
let lis = document.querySelectorAll('ul.fancy li');
Array.from(lis).forEach(function (li) {
console.log(node);
});
querySelectorAll()
方法返回的结果不是一个数组,所以它没有 forEach()
方法,这也正是我们为什么要将它转换成数组的原因。
一般地,对于使用 map()
方法的场景来说, Array.from()
也是一个便捷的方案:
let spans = document.querySelectorAll('span.name');
// map(), generically:
let names1 = Array.prototype.map.call(spans, s => s.textContent);
// Array.from():
let names2 = Array.from(spans, s => s.textContent);
在这个例子中,document.querySelectorAll()
返回的结果依然是一个类数组对象(Array-like object),而不是一个数组, 这就是为什么我们不能在它上面直接调用 map()
方法。在之前的例子,我们将类数组对象(Array-like object)转换成数组以调用 forEach()
方法。在这里,我们通过调用 通用方法
和双参数版本的 Array.from()
方法跳过这个中间步骤。
译者注: 通用方法指的是: 首先是一个方法,然后是这个方法能用于多种类型的对象。 比如
Array.prototype.slice()
方法不仅仅可用于数组,也可用于类数组对象、字符串。
Array.from()
会忽略数组中的空缺, 将它们当做 undefined 元素进行处理:
> Array.from([0,,2])
[ 0, undefined, 2 ]
这意味这也可以使用 Array.form()
方法创建和填充数组:
> Array.from(new Array(5), () => 'a')
[ 'a', 'a', 'a', 'a', 'a' ]
> Array.from(new Array(5), (x,i) => i)
[ 0, 1, 2, 3, 4 ]
如果你想使用固定的值填充数组(前面的两个例子中的第一个)那么 Array.prototype.fill()
方法(见下文)会是一个更好的选择。
另一种 Array.from()
方法的使用情况是将类数组对象(Array-like object)或可迭代对象(Iterable object)转换成 Array 子类的一个实例,举例,如果你创建一个 Array 类的子类 MyArray ,并且想将这样一个对象转换成 MyArray 的一个实例,你只需使用 MyArray.from()
。究其原因,是因为在 ES6 中构造函数之间的继承。(超类的构造函数是其子类构造函数的原型)
class MyArray extends Array {
···
}
let instanceOfMyArray = MyArray.from(anIterable);
你也可以将该功能和 map 一起使用,对你构造函数产生的结果进行一次 map 操作:
// from() – determine the result’s constructor via the receiver
// (in this case, MyArray)
let instanceOfMyArray = MyArray.from([1, 2, 3], x => x * x);
// map(): the result is always an instance of Array
let instanceOfArray = [1, 2, 3].map(x => x * x);
Array.of(item_0, item_1, ···) 可以创建一个由 item_0、item_1 等元素组成的数组。
如果你想把一些值转换成数组,你应当一直使用 Array 字面量方式,特别是当 Array 构造函数不能用的情况下,例如只有一个简单参数且该参数是数字的情况:
> new Array(3, 11, 8)
[ 3, 11, 8 ]
> new Array(3)
[ , , ,]
> new Array(3.1)
RangeError: Invalid array length
但是你如何把值转换成数组子类构造函数的实例?Array.of()
方法帮助你实现(记住,Array 子类的构造函数会继承所有的 Array 类的方法,包括 of()
方法)。
class MyArray extends Array {
···
}
console.log(MyArray.of(3, 11, 8) instanceof MyArray); // true
console.log(MyArray.of(3).length === 1); // true