ram*_*ion 192 javascript arrays map-function
我在Firefox-3.5.7/Firebug-1.5.3和Firefox-3.6.16/Firebug-1.6.2中观察到了这一点
当我开火萤火虫时:
var x = new Array(3)
console.log(x)
// [undefined, undefined, undefined]
var y = [undefined, undefined, undefined]
console.log(y)
// [undefined, undefined, undefined]
console.log( x.constructor == y.constructor) // true
console.log(
x.map(function() { return 0; })
)
// [undefined, undefined, undefined]
console.log(
y.map(function() { return 0; })
)
// [0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?这是一个错误,还是我误解了如何使用new Array(3)
?
Dav*_*son 117
看来是第一个例子
x = new Array(3);
Run Code Online (Sandbox Code Playgroud)
使用未定义的指针创建数组.
第二个创建一个数组,其中包含指向3个未定义对象的指针,在这种情况下,指向它们的指针并非未定义,只有它们指向的对象.
y = [undefined, undefined, undefined]
// The following is not equivalent to the above, it's the same as new Array(3)
y = [,,,];
Run Code Online (Sandbox Code Playgroud)
由于map在数组中的对象的上下文中运行,我相信第一个映射完全无法运行该函数,而第二个映射无法运行.
cst*_*sik 103
我有一个任务,我只知道数组的长度,并需要转换项目.我想做这样的事情:
let arr = new Array(10).map((val,idx) => idx);
Run Code Online (Sandbox Code Playgroud)
要快速创建这样的数组:
[0,1,2,3,4,5,6,7,8,9]
Run Code Online (Sandbox Code Playgroud)
但它没有奏效,因为:看到Jonathan Lonowski的答案,上面有几个答案.
解决方案可能是使用Array.prototype.fill()用任何值填充数组项(即使是未定义的)
let arr = new Array(10).fill(undefined).map((val,idx) => idx);
Run Code Online (Sandbox Code Playgroud)
console.log(new Array(10).fill(undefined).map((val, idx) => idx));
Run Code Online (Sandbox Code Playgroud)
更新
另一个解决方案是:
let arr = Array.apply(null, Array(10)).map((val, idx) => idx);
Run Code Online (Sandbox Code Playgroud)
console.log(Array.apply(null, Array(10)).map((val, idx) => idx));
Run Code Online (Sandbox Code Playgroud)
小智 77
使用ES6,您可以[...Array(10)].map((a, b) => a)
快速轻松地完成!
Ser*_*ern 22
ES6解决方案:
[...Array(10)]
Run Code Online (Sandbox Code Playgroud)
但是不适用于打字稿(2.3)
Tim*_*own 17
阵列是不同的.不同之处在于new Array(3)
创建一个长度为3但没有属性[undefined, undefined, undefined]
的数组,同时创建一个长度为3的数组,以及三个名为"0","1"和"2"的属性,每个属性的值为undefined
.您可以使用in
运算符查看差异:
"0" in new Array(3); // false
"0" in [undefined, undefined, undefined]; // true
Run Code Online (Sandbox Code Playgroud)
这源于一个稍微令人困惑的事实,即如果您尝试在JavaScript中获取任何本机对象的不存在属性的值,它将返回undefined
(而不是抛出错误,就像您尝试引用不存在的变量时那样) ),这与先前已明确设置的属性相同undefined
.
我认为解释此问题的最佳方式是查看Chrome处理它的方式.
>>> x = new Array(3)
[]
>>> x.length
3
Run Code Online (Sandbox Code Playgroud)
所以实际发生的是新的Array()返回一个长度为3但没有值的空数组.因此,当您x.map
在技术上空的阵列上运行时,无需设置任何内容.
undefined
即使它没有值,Firefox也只是'填充'那些空插槽.
我不认为这显然是一个错误,只是一种表达正在发生的事情的糟糕方式.我认为Chrome更"正确",因为它表明阵列中实际上没有任何东西.
在ECMAScript第6版规范中.
new Array(3)
只定义属性length
而不定义索引属性{length: 3}
.请参阅https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array-len第9步.
[undefined, undefined, undefined]
将定义索引属性和长度属性{0: undefined, 1: undefined, 2: undefined, length: 3}
.请参阅https://www.ecma-international.org/ecma-262/6.0/index.html#sec-runtime-semantics-arrayaccumulation ElementList
步骤5.
方法map
,every
,some
,forEach
,slice
,reduce
,reduceRight
,filter
阵列将被检查索引属性HasProperty
内部的方法,所以new Array(3).map(v => 1)
将不调用回调.
有关更多详细信息,请参阅https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array.prototype.map
怎么修?
let a = new Array(3);
a.join('.').split('.').map(v => 1);
let a = new Array(3);
a.fill(1);
let a = new Array(3);
a.fill(undefined).map(v => 1);
let a = new Array(3);
[...a].map(v => 1);
Run Code Online (Sandbox Code Playgroud)
由于其他答案中详细解释的原因,Array(n).map
不起作用。然而,在 ES2015 中Array.from
接受了一个 map 函数:
let array1 = Array.from(Array(5), (_, i) => i + 1)
console.log('array1', JSON.stringify(array1)) // 1,2,3,4,5
let array2 = Array.from({length: 5}, (_, i) => (i + 1) * 2)
console.log('array2', JSON.stringify(array2)) // 2,4,6,8,10
Run Code Online (Sandbox Code Playgroud)
不是错误。这就是定义 Array 构造函数的方式。
来自 MDC:
当您使用 Array 构造函数指定单个数字参数时,您指定了数组的初始长度。以下代码创建一个包含五个元素的数组:
var billingMethod = new Array(5);
Run Code Online (Sandbox Code Playgroud)
Array 构造函数的行为取决于单个参数是否为数字。
该.map()
方法仅包含已显式分配值的数组的迭代元素。即使是显式赋值undefined
也会导致一个值被认为有资格包含在迭代中。这看起来很奇怪,但本质undefined
上是对象上的显式属性和缺失属性之间的区别:
var x = { }, y = { z: undefined };
if (x.z === y.z) // true
Run Code Online (Sandbox Code Playgroud)
对象x
没有名为“z”的属性,而对象y
有。然而,在这两种情况下,财产的“价值”似乎都是undefined
。在数组中,情况类似: 的值length
确实对从 0 到 的所有元素隐式执行值分配length - 1
。.map()
因此,在使用 Array 构造函数和数字参数新构造的数组上调用时,该函数不会执行任何操作(不会调用回调)。