通过map`的`行为上使用创建的阵列混淆`new` [重复](Confused by behavio

2019-07-30 16:01发布

这个问题已经在这里有一个答案:

  • 在阵列未定义值(LEN)初始化 5答案

我受的结果弄得map平在与创建数组new

function returnsFourteen() {
    return 14;
}

var a = new Array(4);
> [undefined x 4] in Chrome, [, , , ,] in Firefox
a.map(returnsFourteen);
> [undefined x 4] in Chrome, [, , , ,] in Firefox

var b = [undefined, undefined, undefined, undefined];
> [undefined, undefined, undefined, undefined]
b.map(returnsFourteen);
> [14, 14, 14, 14]

我预期a.map(returnsFourteen)返回[14, 14, 14, 14]相同b.map(returnsFourteen)因为根据上阵列MDN页 :

如果传递给Array构造的唯一参数是0和2 ** 32-1(含)之间的整数,一个新的JavaScript阵列与该数目的元素创建的。

我解释这意味着a应该有4个元素。

我缺少的是在这里吗?

Answer 1:

当您创建一个数组,像这样:

var arr1 = new Array( 4 );

你得到的长度为数组4 ,但没有元素。 这就是为什么map不转换array -数组没有任何元素进行改造。

在另一方面,如果你这样做:

var arr2 = [ undefined, undefined, undefined, undefined ];

你和阵列还具有长度4 ,但确实有4个元素。

注意到不具有元素,具有元件,其值是之差undefined 。 不幸的是,属性访问表达式会在undefined在这两种情况下的值,因此:

arr1[0] // undefined
arr2[0] // undefined

然而,有一种方法来区分这两个数组:

'0' in arr1 // false
'0' in arr2 // true


Answer 2:

var a = new Array(4);

这定义为4的显式长度,但没有元素的新阵列对象。

var b = [undefined, undefined, undefined, undefined];

这定义了一个新的数组对象为4的隐式长度,用4个元件,每一个与所述值undefined

从文档 :

回调仅对于已分配的值的数组的索引调用; 它不为其调用已被删除或从未分配的值索引。

对于数组a ,有没有已分配值的元素,所以它什么都不做。

对于数组b ,有已分配的值(是的,四种元素undefined是一个值),所以它的所有四个要素的号码映射14



Answer 3:

new Array(len)创建一个空的阵列,并且做了比用填充它不同undefined值:它设置其长度len 。 因此,将其转换为这样的代码:

var newArr = [];
newArr.length = len;

让我们有一些乐趣newArr (假设len = 4 ):

newArr.length; //4
newArr[1] === undefined; //true
newArr.hasOwnProperty(1); //false

这是因为,虽然是4项长,它不包含任何这4个项目。 想象一下,一个空的子弹夹:有,比如说,20发子弹的空间,但它不包含任何人。 他们甚至没有的值设置为undefined ,他们只是......不确定的(这是一个有点混乱。)

现在, Array.prototype.map愉快地沿着你的第一阵列散步,鸣叫和吹口哨,并且每次看到一个数组项时,它调用的函数。 但是,当它沿空子弹夹走,它认为没有子弹。 当然,也有余地的子弹,但是这并不能让他们存在。 在这里,没有任何价值,因为其映射到该值的键不存在。

对于第二阵列,其填充有undefined值,该undefined ,因此是关键。 有里面的东西 b[1]b[3]但没有定义的东西; 但Array.prototype.map并不关心,它会在任何值进行操作,只要它有一个关键。

对于在规范中进一步检查:

  • new Array(len) http://es5.github.com/#x15.4.2.2
  • Array.prototype.map : http://es5.github.com/#x15.4.4.19 (狠抓步骤8.B)


Answer 4:

对行为的一个附加应答console.log 。 朴素简单,输出的是和技术上的错误

让我们考虑这个例子:

var foo = new Array(4),
    bar = [undefined, undefined, undefined, undefined];

console.log( Object.getOwnPropertyNames(bar) );
console.log( Object.getOwnPropertyNames(foo) );

正如我们在结果看到, .getOwnPropertyNames函数返回

["length"]

foo阵列/对象,但

["length", "0", "1", "2", "3"]

用于bar阵列/对象。

因此, console.log只是愚弄你的输出Arrays这只是有一个定义.length ,但没有真正的财产分配。



文章来源: Confused by behavior of `map` on arrays created using `new` [duplicate]