使用Array.prototype.fill和Array.prototype.map未曾注意到的基础

Array.prototype.fill

使用fill配合Array构造函数进行指定个数和初始值的数组创建,并可以通过相关函数的连续调用,完成对数组的修改,从而抛离了forwhile的循环使用。

/**
 * 生成指定长度有统一初始值的数组
 *
 * @param {Number} len - 长度
 * @param {*} val - 初始值
 * @returns {Array[]}
 */
function createSpArray(len, val) {
    return Array(len).fill(val);
}

//使用举例
createSpArray(3,{}); // 输出:(3) [{…}, {…}, {…}]
createSpArray(3,1);  // 输出:(3) [1, 1, 1]

createSpArray(3,1).map((i, idx)=>idx+1); // 输出:(3) [1, 2, 3]

但是需要注意的是,在MDN中提到了,fill方法传递的值若是引用类型的话,则所有数组元素中的元素指向同一引用,若是不够小心的话,很容易出问题。

// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]

Array.prototype.map

MDN中对map函数有这样的一段描述:

map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

这里需要注意的是其中提到的有值索引,如下示例:

const res = Array(3); // res = (3) [empty × 3]
const arrB = res.map(i=>3); // arrB = (3) [empty × 3]

上述示例中,使用Array(3)创建的便是无值索引,此时map的回调函数是未被调用的。再看如下示例:

const res = Array(3).fill(undefined); // b = (3) [undefined, undefined, undefined]
const arrB = res.map(i=>3); // arrB = (3) [3, 3, 3]

通过fill方法,为创建的数组进行元素初始化,便可以正常的使用map函数了。那么如何将原本为有值索引的元素变为无值索引呢?那么就是通过delete进行删除了。示例如下:

const arr = [1,2,3];
delete arr[0]; // arr = (3) [empty, 2, 3];

arr.map(i=>{
    console.info(i);
});

// 输出为:
// 2
// 3    

类似的forEachfilter等对数组遍历操作的函数也有相应的限制,因此使用时需要注意。

Tip:虽然可能用的地方不多,但是知道了,了解了,在解决问题的时候有可能会多一种思路。基础是很重要的。

附一道经典的前端面试题:

在不使用循环的条件下,如何创建一个长度为100的数组,并且数组的每一个元素是该元素的下标?

祝好~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值