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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Array.apply(null,{length: 99}) 逻辑解析

5d5f0dccadc84b5ab9d8d78fe724d8fd.png

数字化管理平台

Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus

权限系统-商城

个人博客地址

一、基础概述

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)

控制台输入:

8baa7c1aaa6d4a19ac2a6fae5ce47c01.png

按照刚刚的理解,把代码换成这个样子应该是没有问题的。然而打印结果告诉我们刚刚那样子地理解应该是不对的, 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

f2aca47a25434993a6d07761404101cd.png


相关文章
|
9月前
|
存储 区块链 数据安全/隐私保护
DApp互助预约排单系统开发设计规则逻辑解析
DApp互助预约排单系统开发设计规则逻辑解析
|
2月前
|
SQL 存储 NoSQL
实时计算 Flink版产品使用合集之使用ParameterTool.fromArgs(args)解析参数为null,该怎么处理
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
28天前
|
自然语言处理 JavaScript 前端开发
【JavaScript】JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析
【JavaScript】JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析
24 3
|
17天前
|
SQL 关系型数据库 MySQL
MySQL外键约束行为解析:CASCADE, NO ACTION, RESTRICT, SET NULL
MySQL外键约束行为解析:CASCADE, NO ACTION, RESTRICT, SET NULL
16 0
|
2月前
|
PHP
Trying to access array offset on value of type null
你就可以避免在null值上尝试访问数组偏移量的错误。 总的来说,当你遇到这个错误时,你应该回顾你的代码,确保在尝试访问数组偏移量之前,相关的变量已经被正确地初始化为一个数组,并且不是null。
|
2月前
|
存储 SQL 关系型数据库
drds逻辑表与物理解析
drds逻辑表与物理解析
59 5
|
2月前
|
编解码 计算机视觉 Python
IPC机制在jetson中实现硬解码视频流数据通信的逻辑解析
IPC机制在jetson中实现硬解码视频流数据通信的逻辑解析
105 0
|
2月前
|
测试技术 数据库
深入解析MyBatis-Plus中的逻辑删除功能及实例
深入解析MyBatis-Plus中的逻辑删除功能及实例
399 0
|
2月前
|
Java 数据库连接 API
SpringBoot【问题 01】借助@PostConstruct解决使用@Component注解的类用@Resource注入Mapper接口为null的问题(原因解析+解决方法)
SpringBoot【问题 01】借助@PostConstruct解决使用@Component注解的类用@Resource注入Mapper接口为null的问题(原因解析+解决方法)
220 0
|
2月前
ES6的Array.from({length:N})方法创建长度为N的undefined数组,等价于 [...Array(N)]
ES6的Array.from({length:N})方法创建长度为N的undefined数组,等价于 [...Array(N)]

推荐镜像

更多