当前位置: 首页 > news >正文

Array.apply(null,{length: 99}) 逻辑解析

在这里插入图片描述

一、基础概述

vue 教程中有一段 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('ul',Array(20).map(function () {return createElement('li', 'list item')}))
}

演化成 JS 代码如下:

# apply 模式
const list = Array.apply(null, {length: 99
})
console.log("list:",list)# Array 参数模式
const list2 = Array(99)
console.log("list2:",list2)

控制台输入:
在这里插入图片描述
按照刚刚的理解,把代码换成这个样子应该是没有问题的。然而打印结果告诉我们刚刚那样子地理解应该是不对的, Array.apply(null, { length: 99 })和Array(99) 这两句代码还是有区别的,那么区别是什么?

二、解析

2.1 apply 函数方式

ES5开始 apply 函数的第二个参数除了可以是数组外,还可以是类数组对象(即包含length属性,且length属性值是个数字的对象)。对象{length: 2}就是一个类数组对象,因为没有初始化下标0,1的值,所以获取0,1下标的值得到的都是undefined。

console.log(list[0]); // undefined
console.log(list[1]); // undefined// 类数组可以转成真正的数组
var arr = Array.prototype.slice.apply({length: 2});
console.log(Array.isArray(arr)) // true

这样表达式 Array.apply(null, { length: 2}) 就等价于如下代码:

// { length: 2 } 作为 Array.apply 第二个参数等同于 [undefined, undefined] 作为 Array.apply 第二个参数
Array.apply(null, [undefined, undefined]); // 等价于 apply 方法的执行结果
Array(undefined, undefined); // Array 属于安全的构造函数,上面直接调用和 new 方式调用等价
new Array(undefined, undefined); 

这样就很容易知道该表达式的值是一个长度为2,且每个元素值都被初赋值为 undefined 的数组(注意此时不是数组元素没有初始化,而是初始化成undefined,这就是跟 Array(2) 的区别)

为啥非要写那么复杂呢?

即map函数并不会遍历数组中没有初始化或者被 delete 的元素(有相同限制还有 forEach, reduce 方法)。所以写这么“复杂”就是为了实现:创建一个长度为 99,且每个元素都被初始化的数组。这样 map 方法就可以循环 99 次了。

// 被初始化的数组
let apply = Array.apply(null, { length: 99 }).map(function (item, index) {return {index: index, // 循环99次};
});// 未被初始化的数组
let data = Array(99).map(function (item, index) {return {index: index, // 不会被执行};
});

该表达式还可以修改成:

Array.apply(null, Array(99)); // 第二个参数用 Array(99) 代替 {length: 99}

使用 ES6 API 创建初始化数组:

# 方式一
Array.from({length: 99})# 方式二
Array(99).fill(null)

2.2 构造函数 + 一个数字参数

直接调用Array函数跟new方式调用是等价的,即

let arr = Array(99)# 等价于
let arr = new Array(99);

表示创建一个长度为 99 的数组,注意该数组的元素并没有被初始化([empty ×99]),即

console.log(0 in a); // false
console.log(1 in a); // false, 因为数组下标0,1还未初始化
console.log(a[0]); // undefined, 因为数组下标0还未初始化,访问不存在的属性返回undefined

关注公众号:前端知识分享喵,获取前端学习资料
在这里插入图片描述

http://www.lryc.cn/news/17379.html

相关文章:

  • Web前端开发常用工具推荐(内含学前端必备软件资源)
  • 【python】考前复习,python基础语法知识点整理
  • 3个月,入门网络安全并找到工作
  • 你会用 TypeScript 的条件类型吗?
  • 云原生丨一文教你基于Debezium与Kafka构建数据同步迁移(建议收藏)
  • 顶象APP加固的“蜜罐”技术有什么作用
  • 训练一个ChatGPT需要多少数据?
  • 【GlobalMapper精品教程】053:打开dbf文件并生成有坐标系的shp数据
  • 图像亮度调整
  • 精简版SDL落地实践
  • 第一回:Matplotlib初相识
  • 怎么找回电脑删除的图片
  • 【Linux】进程状态与进程优先级
  • Python+Qt生日提醒
  • 第二章 编写MBR主引导记录
  • Android 9.0 仿ios的hotseat效果修改hotseat样式
  • 量化私募投资百亿头部量化私募企业在招岗位:AI算法工程师21/22/23届,校招/秋招/社招都看年base60-200万
  • 百度西交大大数据菁英班目标检测竞赛
  • Redisson实现分布式锁
  • 【HID基础知识】
  • 工赋开发者社区 | 工业数字孪生:西门子工业网络与设备虚拟调试案例(TIA+MCD+SINETPLAN)
  • 将闲置的Ipad作为Windows的副屏(Twomon SE)
  • 浮点数在内存中的存储——“C”
  • 华为OD机试 C++ 实现 - 租车骑绿岛
  • Spring Cloud Nacos源码讲解(三)- Nacos客户端实例注册源码分析
  • 位运算(C/C++)
  • 哈希表题目:设计哈希映射
  • ​力扣解法汇总1238. 循环码排列
  • [数据结构]时间复杂度与空间复杂度
  • Codeforces Round #848 (Div. 2)(A~D)