Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Array.from 方法简介

  前面几篇文章一直在提Array.from,但突然发现还没好好介绍过这玩意儿。其实这东西已经很流行了吧,其流行程度应该已经和箭式函数差不多了,在推特上经常可以看到。而且Firefox也已经支持。当目前国内好像还没有什么相关资料,至少我在百度上没搜到。
  如果要初始化一个具有n个元素数组大家都是怎么做的?new Array(n)吗?其实这样得到的结果是一个只有长度没有实际元素的东西,一遍历就露馅了:
var n=10;
var s=new Array(n);
console.log(s.length); //有长度
for(var i in s)
  console.log("不会被执行到,因为数组里实际上");
  Array.from的行为是对可迭代对象直接调用迭代器,对不可迭代对象使用数组迭代器来遍历。而数组迭代器的行为则是取出对象的length属性,然后遍历这个length逐个取下标元素。所以这个方法得到的数组总是存在每一个元素的,不会像new Array(n)一样,只有个长度没有内容。
var n=10;
var s=Array.from({length:n}); //[undefined * 10]
for(var i in s)console.log(i); //是确实可以遍历的
Array.from("test"); //["t","e","s","t"] function*g(){ for(var i=0;i<10;i++)yield i; };
Array.from(g()); //[0,1,2,...,9]
  Array.from方法还有其它参数。其第二个参数是一个回调函数,所有遍历到的元素都会经过这个函数处理后返回。而这个函数的thisArray.from的第三个参数决定。简单地说,这第二和第三个参数相当于执行了一个map操作。
var arr=Array.from({length:10},(e,i)=>i);
//等价于
var arr=Array.from({length:10}).map((e,i)=>i);
  在浏览器没有支持from方法之前,我们可以借用强类型数组不稀疏的特性来实现类似的功能,比如这段代码同样可以实现上面的行为: var map=Array.prototype.map;
var arr=map.call(new Uint8Array(10),function(e,i){ return i; });
  最后,这个from方法还有另一个特点,它并不是Array对象独有的,可以call着使用。this会被尝试作为返回值的构造器,当然如果它不是构造器的话会使用默认的Array构造器。另外如果from方法的第一个参数是可迭代对象的话,那么在创建返回值的实例时就不会传入任何参数(因为可迭代对象无法确定长度),否则会将其从第一个参数中取出的length属性作为构造参数。总之,这意味着它是可继承的。比如可以写这样的代码: //一个继承于Array的子构造器
function A(len){
  console.log("len="+len);
};
Object.setPrototypeOf(A,Array);
A.prototype=[];

//从这个子构造器上调用from
//由于数组是可迭代对象,所以没有参数被传入构造器
var result=A.from([1,2,3]); //len=undefined

//结果依然是这么子构造器的实例
console.log(result instanceof A); //true

//这个对象是不可迭代对象,所以length会被传入构造器
A.from({length:3}); //len=3
  关于这个from方法,其实也没其它特殊的地方了。如果有什么的话,这些坑在之前的文章中就已经踩平了,具体请参考:
    JavaScript拟数组的概念
    纠结的函数 length 属性与 Array.from
  另外,也建议参考MDN,上面有比较详细的介绍,不过是英文的
    MDN Array.from
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^