完全解析Array.apply(null, { length: 1000 })
Array.apply(null, { length: 1000 })
在阅读VueJS教程时有这么段demo code:
render: function (createElement) {
return createElement('div',
Array.apply(null, { length: 20 }).map(function () {
return createElement('p', 'hi')
})
)
}
其中这个表达式Array.apply(null, { length: 20 })有点让人费解。第一感觉这个表达式就是为了创建一个长度为20的数组,但表达式Array(20)也可以实现这个功能啊,为啥非要写那么复杂呢?于是乎就想,如果是这样子,那么我把这一段代码换成 Array(20) ,变成下面这样:
render: function (createElement) {
return createElement('div',
Array(20).map(function () {
return createElement('p', 'hi')
})
)
}
对比代码:
let apply = Array.apply(null, { length: 20 }).map(function (item, index) {
return {
index: index,
};
});
console.log("Array.apply", apply);
let data = Array(20).map(function (item, index) {
return {
index: index,
};
});
console.log("Array()", data);
效果图:

那么按照刚刚的理解,把代码换成这个样子应该是没有问题的。然后运行代码,发现浏览器什么都没有出来,连个错都没有报,这样子就很明显地说明了,刚刚那样子地理解应该是不对的, Array.apply(null, { length: 20 })和Array(20) 这两句代码还是有区别的,那么区别是什么?
基础1: Array构造函数
直接调用Array函数跟new方式调用是等价的,即:
let a = Array(2); // 等价于let a = new Array(2);
表示:创建一个长度为2的数组,注意该数组的元素并没有被初始化,即:
console.log(0 in a); // false
console.log(1 in a); // false, 因为数组下标0,1还未初始化
console.log(a[0]); // undefined, 因为数组下标0还未初始化,访问不存在的属性返回undefined
基础2: apply函数
ES5开始apply函数的第二个参数除了可以是数组外,还可以是类数组对象(即包含length属性,且length属性值是个数字的对象)。对象{length: 2}就是一个类数组对象,因为没有初始化下标0,1的值,所以获取0,1下标的值得到的都是undefined。
console.log(a[0]); // undefined
console.log(a[1]); // undefined
// 可以转成真正的数组
var a = Array.prototype.slice.call({length: 2});
console.log(Array.isArray(a)) // true
再看表达式Array.apply(null, { length: 2})的值
温故了基础后再看表达式Array.apply(null, { length: 2 })他就等价于:
// 1 熟悉一点: {length: 2}作为Array.apply第二个参数等同于[undefined, undefined]作为Array.apply第二个参数
Array.apply(null, [undefined, undefined]);
// 2 再熟悉一点:apply方法的执行结果
Array(undefined, undefined);
// 3 再再熟悉一点:Array方法直接调用和new方式调用等价
new Array(undefined, undefined);
这样就很容易知道该表达式的值是一个长度为2,且每个元素值都被初赋值为undefined的数组(注意此时不是数组元素没有初始化,而是初始化成undefined,这就是跟Array(2)的区别)。
为啥非要写那么复杂呢?
即map函数并不会遍历数组中没有初始化或者被delete的元素(有相同限制还有forEach, reduce方法)。OK,疑问到此终于真相大白了:写这么“复杂”就是为了实现:创建一个长度为20,且每个元素都被初始化的数组。这样map方法就可以循环20次了。
// 被初始化的数组
let apply = Array.apply(null, { length: 20 }).map(function (item, index) {
return {
index: index, // 循环20次
};
});
// 未被初始化的数组
let data = Array(20).map(function (item, index) {
return {
index: index, // 不会被执行
};
});
如果为了少写几个字的话还可以把该表达式修改成:
Array.apply(null, Array(20)); // 第二个参数用Array(20)代替{length: 20}
还可以使用ES6 API创建初始化数组:
// 方法1:
Array.from({length: 20})
// 方法2
Array(20).fill(null)
完全解析Array.apply(null, { length: 1000 })的更多相关文章
- Array.apply(null,{length:20})与new Array(20)的区别
Array.apply(null,{length:20}) 这句代码的实际意义:创建长度为20的一个数组,但并非空数组. 跟new Array(20)的区别在于,前一种创建方式,得到的数组中的每一个元 ...
- 分析Array.apply(null, { length: 5 })
Array.apply(null, { length: 5 }) 和 Array(5)有什么不同 注意:ES5,apply函数的第二个参数除了可以是数组外,还可以是类数组对象 // 类转成真正的数组 ...
- JavaScript中如何理解如何理解Array.apply(null, {length:5})
先来看一个问题: 如何理解Array.apply(null, {length:5})的{length:5}? 我测试过Array.apply(null, {length:5}) //返回[undefi ...
- Array.apply(null,{length:6}).map()
map定义和方法 map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理的后值. map()方法按照原始数组元素顺序依次处理元素. 注意: map不会对空数组进行检测 map不会改变原始 ...
- Array.apply(null, {length: 20})和Array(20)的理解
话说今晚在学习Vue.js教程里:Render函数,这一章节是发现了一个问题,就是利用下面的这个render函数可以渲染20个重复的段落: render: function (createElemen ...
- Array.apply(null, {length: 2}) 的理解
// apply 的第二参数通常是数组 但是也可以传递类数组对象{length: 2}console.log(Array.apply(null, {length: 2})) // [undefined ...
- Array.apply 方法的使用
Array.apply(null, {length: 5}) length为特殊字段,意思是生成一个长度为5的数组,由于没赋值,所以都是undefined; 如果要赋值,可以这样 console.lo ...
- iOS 后台返回json解析出现的null的解决办法
在后台返回值为Null为空时,我们代码没有判断时,程序就会崩溃.当时一直很疑惑是为啥,后来发现是数据问题,由于服务器的数据库中有些字段为空,然后以Json形式返回给客户端时就会出现这样的数据.当我们通 ...
- Math.max.apply(null,arr)求最大值
1.首先了解一下call和apply call 和 apply 的第一个参数是null/undefined时函数内的this指向window 或global call/apply 用来改变函数的执行上 ...
随机推荐
- 实现领域驱动设计 - 使用ABP框架 - 什么是领域驱动设计?
前言: 最近看到ABP官网的一本电子书,感觉写的很好,翻译出来,一起学习下 (Implementing Domain Driven Design) https://abp.io/books DDD简介 ...
- DBPack 赋能 python 微服务协调分布式事务
作者:朱晗 中国电子云 什么是分布式事务 事务处理几乎在每一个信息系统中都会涉及,它存在的意义是为了保证系统数据符合期望的,且相互关联的数据之间不会产生矛盾,即数据状态的一致性. 按照数据库的经典理论 ...
- 使用强大的DBPack处理分布式事务(PHP使用教程)
主流的分布式事务的处理方案 近些年,随着微服务的广泛使用,业务对系统的分布式事务处理能力的要求越来越高. 早期的基于XA协议的二阶段提交方案,将分布式事务的处理放在数据库驱动层,实现了对业务的无侵入, ...
- meet in the middle 复习笔记
前言 若干年前看过现在又忘了.这么简单都忘 所以今天来重新复习一下. 正题 考虑这样的问题: 给定 \(n\) 个物品的价格,你有 \(m\) 块钱,每件物品限买一次,求买东西的方案数. \(n\le ...
- Tapdata Cloud 2.1.4 来啦:数据连接又上新,PolarDB MySQL、轻流开始接入,可自动标记不支持的字段类型
需求持续更新,优化一刻不停--Tapdata Cloud 2.1.4 来啦! 最新发布的版本中,在新增数据连接之余,默认标记不支持同步的字段类型,避免因此影响任务的正常运行. 更新速览 ① 数 ...
- 攻防世界MISC进阶区---41-45
41.Get-the-key.txt 得到无类型文件,扔进kali中,strings一下,得到了一堆像flag的内容 扔进010 Editor中,搜索关键字,发现一堆文件,改后缀为zip 打开,直接得 ...
- docker for window WSL 2 installation is incomplete 错误,导致docker无法启动
1.错误截图如下: 2.错误原因:由于wsl2版本旧,根据提示让我们手动更新包,去微软官网下载最新wsl2后,安装完成重启即可解决. 3.下载地址:download地址
- C# MVCapi跨域问题
he 'Access-Control-Allow-Origin' header contains multiple values ', *', but only one is allowed. Or ...
- STM32与物联网02-网络数据收发
在上一节中,介绍了 ESP8266 的使用方法.不过上一节中都是通过串口调试工具手动发送信息的方式来操作 ESP8266 ,这肯定不能用于实际开发.因此,本节介绍如何编写合适的程序来和 ESP8266 ...
- 总结几个简单好用的Python人脸识别算法
原文连接:https://mp.weixin.qq.com/s/3BgDld9hILPLCIlyysZs6Q 哈喽,大家好. 今天给大家总结几个简单.好用的人脸识别算法. 人脸识别是计算机视觉中比较常 ...