我受的结果弄得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个元素。
我缺少的是在这里吗?
当您创建一个数组,像这样:
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
var a = new Array(4);
这定义为4的显式长度,但没有元素的新阵列对象。
var b = [undefined, undefined, undefined, undefined];
这定义了一个新的数组对象为4的隐式长度,用4个元件,每一个与所述值undefined
。
从文档 :
回调仅对于已分配的值的数组的索引调用; 它不为其调用已被删除或从未分配的值索引。
对于数组a
,有没有已分配值的元素,所以它什么都不做。
对于数组b
,有已分配的值(是的,四种元素undefined
是一个值),所以它的所有四个要素的号码映射14
。
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)
对行为的一个附加应答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
,但没有真正的财产分配。