微信订阅号: Rabbit_svip
Array.from 方法用于将两类对象转换为真正的数组:
1, 类似数组的对象, 可以理解为 "伪数组"
2, 可遍历对象 (比如字符串)
什么是伪数组?
伪数组都有一个基本的特点: 必须有 length 属性.
- let arrayLike = {
- "0": "a",
- "1": "b",
- "2": "c",
- "length": 3
- }
像上面的 arrayLike 对象, 有 length 属性, key 也是有序序列.
所以可以遍历, 也可以查询长度. 但却不能调用数组的方法. 比如 push,pop 等方法.
在 ES6 之前, 还有一个常见的伪数组: arguments.
arguments 看上去也很像一个数组, 但它没有数组的方法.
比如 arguments.push(1) , 这样做一定会报错.
ES5 的做法
在 ES6 问世之前, 开发者通常需要用以下的方法把伪数组转换成数组.
方法 1: 遍历
- // 通过 makeArray 方法, 把数组转成伪数组
- function makeArray(arrayLike) {
- let result = [];
- for (let i = 0, len = arrayLike.length; i <len; i++) {
- result.push(arrayLike[i]);
- }
- return result;
- }
- function doSomething () {
- let args = makeArray(arguments);
- console.log(args);
- }
- doSomething(1, 2, 3);
- // 输出: [1, 2, 3]
这个方法虽然有效, 但要多写很多代码.
方法 2:Array.prototype.slice.call
- function doSomething () {
- let args = Array.prototype.slice.call(arguments);
- console.log(args);
- }
- doSomething(1, 2, 3);
- // 输出: [1, 2, 3]
这个方法的功能和 方法 1 是一样的, 虽然代码量减少了, 但不能很直观的让其他开发者觉得这是在转换.
ES6 的做法
直到 ES6 提供了 Array.from 方法完美解决以上问题.
- function doSomething () {
- let args = Array.from(arguments);
- console.log(args);
- }
- doSomething('一', '二', '三');
- // 输出: ['一', '二', '三']
Array.from 的主要作用就是把伪数组和可遍历对象转换成数组的.
说 "主要作用" 的原因是因为 Array.from 还提供了 2 个参数可传. 这样可以延伸很多种小玩法.
Array.from 的第二个参数是一个函数, 类似 map 遍历 方法. 用来遍历的.
Array.from 的第三个参数接受一个 this 对象, 用来改变 this 指向.
第三个参数的用法 (不常用)
- let helper = {
- diff: 1,
- add (value) {
- return value + this.diff; // 注意这里有个 this
- }
- };
- function translate () {
- return Array.from(arguments, helper.add, helper);
- }
- let numbers = translate(1, 2, 3);
- console.log(numbers); // 2, 3, 4
其他玩法
创建长度为 5 的数组, 且初始化数组每个元素都是 1
- let array = Array.from({
- length: 5
- }, () => 1)
- console.log(array)
- // 输出: [1, 1, 1, 1, 1]
第二个参数的作用和 map 遍历 差不多的, 所以 map 遍历 有什么玩法, 这里也可以做相同的功能. 就不多赘述了.
把字符串转成数组
- let msg = 'hello';
- let msgArr = Array.from(msg);
- console.log(msgArr);
- // 输出: ["h", "e", "l", "l", "o"]
最后一个问题: 如果传一个真正的数组给 Array.from 会返回什么结果?
答案是: 会返回一个一模一样的数组.
来源: http://www.jianshu.com/p/9238a3b6d538