17.1 新的数组类方法

Array 类对象上增加了几个专有方法。

17.1.1 Array.from(arrayLike, mapFunc?, thisArg?)

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() 方法,这也正是我们为什么要将它转换成数组的原因。

17.1.1.1 Mapping via Array.from()

一般地,对于使用 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() 方法不仅仅可用于数组,也可用于类数组对象、字符串。

17.1.1.2 数组中的空缺(holes)

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() 方法(见下文)会是一个更好的选择。

17.1.1.3 from() 在 Array 子类中的使用

另一种 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);

17.1.2 Array.of(...items)

Array.of(item_0, item_1, ···) 可以创建一个由 item_0、item_1 等元素组成的数组。

17.1.2.1 Array.of() 可以作为 Array 字面量用于 Array 子类

如果你想把一些值转换成数组,你应当一直使用 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

results matching ""

    No results matching ""