生成一个元素值为‘a’,长度为100的数组

  • Post author:
  • Post category:其他


测试一个问题时,希望创建一个数组变量,长度为100,每个元素值为‘a’。第一反应就是先创建一个length为100的数组,再用map方法把每个元素转为’a’,写法如下:

let arr = Array(100).map(item=>item='a')

结果瞬间打脸,得到的数组是[empty × 100],根本不是需要的。

为啥会这样呢,查map在mdn中的定义,发现了一段关键的话:

callback is invoked only for indexes of the array which have assigned

values (including undefined). It is not called for missing elements of

the array; that is:

  1. indexes that have never been set;
  2. indexes which have been deleted.

也就是说,只有指定了值的元素才会触发map的回调函数,没有初始化或者索引被删除的元素是无法被遍历的。

回到开头的问题,Array(100)生成的数组其中的元素没有被初始化,所以也就没有触发回调函数,数值没有变更。

那么我们的问题可以拆解一下:

  1. 生成长度为100的数组
  2. 初始化元素
  3. map回调函数改变元素值


思路一:


先将数组转为字符,再转回数组类型

let arr = Array(100).toString().split(',').map(item=>item='a')


思路二


还可以巧妙借助apply方法

let arr = Array.apply(null,{length:100}).map(item=>item='a')

apply的第一个参数为null时,会将apply前面的fun函数指向全局函数,第二个参数可以为数组或类数组,类数组会转成数组。

Array.apply(null,{length:100})相当于Array.apply(null,[undefined,undefined,…]),数组已被初始化,元素值为undefined。


思路三


受前面类数组转为数组的启发,使用Array.from来处理。

let arr = Array.from({length:100},(v,k)=>'a')

Array.from是ES6新增的方法,可以将类数组和可迭代对象转为数组,并且自身就包含类似map的处理方法。

// 语法结构
Array.from(arrayLike[, mapFn[, thisArg]])

那么,[].slice.call()同样可以将类数组转为数组,是不是可以用[].slice.call()来进行类似的操作呢?

答案是否定的。

let _arr = [].slice.call({length:100})
console.log(_arr)
// [empty x 100]

但是这样得到的数组元素没有被初始化。这个从V8源码中可以看出端倪。

Array.from部分源码:

Array.from部分源码

slice部分源码:

slice方法部分源码

slice会先判断数组中是否包含某个索引,没有就跳过,而Array.from会直接对数组赋值,没有初始值就会赋值为undefined。所以在这里,Array.from(100)得到的是[undefined,…],slice得到的是[empty × 100],slice是没办法直接满足我们的要求的。

类数组对象:包含length属性,且length属性值为整数的对象。

可迭代对象:具有原生iterator接口的数据结构,包括Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象。



总结

最后,生成指定长度指定元素值的数组,方法如下:

  1. new Array
let arr = Array(100).toString().split(',').map(item=>item='a')
  1. Array.apply
let arr = Array.apply(null,{length:100}).map(item=>item='a')
  1. Array.from
let arr = Array.from({length:100},(v,k)=>'a')
  1. for循环
var arr1 = new Array(100);
 for(var i=0;i<arr1.length;i++){
     arr1[i] = i;
 }
  1. push
var arr = new Array();
for(var i=0;i<100;i++){
    arr.push(i);
}



版权声明:本文为TinaSlowDown原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。