资讯专栏INFORMATION COLUMN

new Array(1) 和 [undefined] 一样嘛?

yzd / 2866人阅读

摘要:实际上这个操作不是创建一个项都是的数组,它创建的是一个只有长度的数组,里面的每项都是没有被赋过值的可以想象实际上是创建了一个的数组。函数的回调函数只会被赋过值的项调用。没有为数组中的项赋过值,而为数组中的项赋了一个值。

一 问题描述

最近在开发中碰到一个很奇怪的问题,请看下面代码

const newArr = new Array(3).map((item) => {
  return item = {
    name: "Chris xiong"
  }
})
console.log(newArr)

大家觉得这段代码的输出结果是多少呢?很多小伙伴会觉得结果一定是这样的
[{name: "Chris xiong"}, {name: "Chris xiong"}, {name: "Chris xiong"}]
这么想的同学请把上面那段代码放进控制台里输出一下。你会发现,结果不是你想象的那样。上述这段代码的执行结果是(3) [undefined × 3]
大家一定会感到困惑,为什么输出的是undefined * 3呢?, 是因为我们的数组里的值是undefined,所以不能给undefined赋值嘛?先不着急,我们再来看下面一段代码

const arrA = [undefined, undefined, undefined]
const newArr = arrA.map((item) => {
  return item = {
     name: "Chris xiong"
   }  
})
console.log(newArr)

如果上面的问题是因为数组的值是undefined造成的话,那么第二个demo也一定是(3) [undefined × 3]。那么事实又是什么呢?这里不卖关子了。这里的输出结果为
[{name: "Chris xiong"}, {name: "Chris xiong"}, {name: "Chris xiong"}]
奇怪了,这里为什么又输出的是我们想要的结果呢?很气有没有?下面我们一起来探究一下这个让人困惑的问题。

二 原因探究

首先我们来看看Array.prototype.map的定义Array.prototype.map。大家注意这一句

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, indexes that have never been set, which have been deleted or which have never been assigned a value).

map函数的回调函数只会被数组中那些被赋予了值的项调用(包括赋了undefine的值),而不会被那些重来没有设置过值,或者被删除了的项调用。(注意这里的重来没有被赋给值)
那么现在我们就知道了,如果数组中的项没有被赋过值,那么这项就不能调用callback函数。
实际上new Array(x)这个操作不是创建一个x项都是undefined的数组,它创建的是一个只有长度的数组,里面的每项都是没有被赋过值的(可以想象new Array(3)实际上是创建了一个[, ,]的数组
我们来看下面一段代码

const arrA = [ , , ]
const newArr = arrA.map((item) => {
  return item = {
     name: "Chris xiong"
   }  
})
console.log(newArr)

上面这段代码和第一段代码执行结果一样。
综合以上,我们找出了问题的原因。
(1)map函数的回调函数只会被赋过值的项调用。
(2)new Array(1) 和 [undefined]不一样。new Array(1)没有为数组中的项赋过值,而[undefined]为数组中的项赋了一个undefined值。

三 解决方法

那么如果我们想像上面那样创建一个新数组怎么办呢?知道原因就很简单了,我们在用new Array创建数组之后,再为数组的每一项随便赋个什么值就行了。一般使用fill方法

const newArr = new Array(3).fill().map((item) => {
  return item = {
    name: "Chris xiong"
  }
})
console.log(newArr)

输出的结果就是
[{name: "Chris xiong"}, {name: "Chris xiong"}, {name: "Chris xiong"}]

注:
(1) fill函数为数组填充值。fill函数

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84793.html

相关文章

  • 数组空位元素的处理

    之前看到知乎上的这道题:如何不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标?,在这个问题里面题主提到,他写了这么一段代码: use strict let arr = Array(100).map( (item,idx) => idx) 结果arr是一个有100个空位的数组:showImg(https://segmentfault.com/img/bVtNMu);这说...

    Yujiaao 评论0 收藏0
  • javascript数组知识基础讲解(上)

    摘要:稀疏数组遍历上面这段代码可以看出,在遍历数组的时候是会跳过这些空白单元,直接找到下标为的值。 js是一门拥有非常强表达能力的语言,当你知道你要做什么的时候,它能帮助你更加出色的完成这件事情。当然,想要成为一名出色的前端工程师,需要的是更多的精力跟学习。所以大家要跟我一起努力哦! 数组基本了解 数组(array),字符串(string),和数字(number)算是一个程序最基本的组成部分...

    cgh1999520 评论0 收藏0
  • javascript判断数据类型

    摘要:操作符刚说完,肯定又有人想用,但是,真的有用吗操作符用来比较两个操作数的构造函数,运算符与运算符相似,用于识别正在处理的对象的类型。 题目 实现一个函数typeof(),输入一个数据,返回数据的基本类型。如: typeof([]) => array typeof({}) => object typeof() => string 等等 解析 由于javascript这门语言辉(keng)...

    Lyux 评论0 收藏0
  • 阅读redux源码

    摘要:一个没有返回值都会有警告,所以我们写的时候都会指定一个默认返回值。执行接收参数,如果参数个数是,直接执行,上文的的执行结果返回值是一个函数,作为参数的话,长度确实是,所以直接返回了,也就是,所以这块是不需要的。 redux源码解析 什么是redux Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 为什么需要使用redux 提供了和双向绑定思想不同的单向数据流,...

    endless_road 评论0 收藏0
  • 霸道总裁之js对象

    摘要:应该一样啊骚年,不要把你判断值类型的方法套在我们伟大的对象上。还记得上面说的,对象是由构造器函数创建的吗所以说有构造器的类型,都是对象。其他的类型都有构造器,所以再次声明一切都是对象是很有道理的。 对象 在大多数人的眼里,js是一门面向对象(Object-Oriented)的语言,但是它与其他的语言比如c++,java 这些面向对象语言 略有不同。!!!艹,说人话那问几个问题吧: 1....

    TerryCai 评论0 收藏0

发表评论

0条评论

yzd

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<