MiaoMiao'S Dev Life
  • 首页
  • 技术专栏
首页 / 随笔 / new Array(1) 和 [undefined] 一样嘛?

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

随笔 • 7 years ago

一 问题描述

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

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函数

Like (0)
Comments (0)
Back
Leave a comment
Related Posts
初探模块系统02—如何让模块支持AMD/CMD和commonjs标准
前段时间在看一些前端模块化方面的知识,现在自己就来写一个符合amd/cmd 和commonjs标准的模块。在文中会穿插一些AMD/CMD,commonjs的基础知识,主要是为了让自己复习一下。了解的同学们可以直接略过。 一 原模块 该模块是一个实现类数组转为数组功能的模块 (function(arrayLike){ ...
7 years ago
初探flex布局
一 flex布局 1.1 flex概述 flex布局是一种较新CSS盒子模型,在flex布局模型中,弹性容器的子元素的排布可以比较灵活,可以根据容器的大小自动扩展或收缩其大小。也可以比较灵活的处于容器的的某一位置上。所以flex的应用场景很多,比如我们碰到需要元素居中的应用场景时,flex布局就变得很有用了。更多关于f ...
8 years ago
记一次 vue项目中使用 scss
一 概述 随着sass/less等css预处理器的出现,编写css变的越来越有乐趣。所以现在越来越多的人在项目中喜欢使用scss或者less。(我自己就是一个)。由于最近在写一个vue项目。所以就把写项目期间每天的一些知识点写在博客里。所以最近的博客应该都会和vue有关。今天要和大家分享的就是如何在vue项目中引入sc ...
8 years ago
© 2016-2025 All Rights Reserved⋅Developed by nicetheme⋅浙ICP备19034990号
  • 首页
  • 技术专栏
Search (0)
    Load more...
    Tags
    css docker es6 git html js typescript vue 动态表单 整洁架构