JavaScript 中带有 new Array() 的未定义值
Posted
技术标签:
【中文标题】JavaScript 中带有 new Array() 的未定义值【英文标题】:Undefined values with new Array() in JavaScript 【发布时间】:2016-05-08 02:51:01 【问题描述】:查看一些 javascript 代码,我看到了(类似的):
var arr = Array.apply(null, length: 10);
阅读 Function.prototype.apply() 的 MDN 文档后,我了解到虽然它通常需要一个数组作为其第二个参数,该数组是要传递给被调用函数的参数数组,
您也可以使用任何类型的类似数组的对象,因此在实践中这意味着它将具有属性长度和范围内的整数属性(0...长度)。
所以据我所知,它调用 Array() 就好像它传递了 10 个参数,但由于它没有定义任何这些“整数属性”,就好像它传递了 10 个未定义的参数。 正确吗?
console.log(arr);
产量
[未定义, 不明确的, 不明确的, 不明确的, 不明确的, 不明确的, 不明确的, 不明确的, 不明确的, 未定义]
这与结果完全不同
var barr = new Array(10);
console.log(barr);
这是
[ , , , , , , , , , ]
这些数组的行为也不同。
console.log(arr.map(function(item) return 'hi';));
console.log(barr.map(function(item) return 'hi';));
给予
['嗨','嗨','嗨','嗨','嗨','嗨','嗨','嗨','嗨','嗨']
[ , , , , , , , , , ]
我想知道为什么第二个地图功能不起作用。所以我检查了console.log(1 in arr);
,它给出了 true 和 `console.log(1 in barr);'这给了 false.
所以我目前的猜测是,arr 是一个数组,其中包含 10 个作为整数属性的变量,每个变量的值都为 undefined,而 barr 是一个数组,虽然它的长度为 10,但具有没有整数属性。 Array.apply 之所以有效,是因为它询问 length: 10 它的属性 0 是什么,接收 undefined,然后将 undefined 分配给该属性0 它正在构造的数组,依此类推。我的推理正确吗?真的有没有更骇人听闻的方法来定义一个数组,该数组包含其范围内每个索引的未定义整数属性,而不是根本没有整数属性?因为看这个,我觉得new Array()
没什么用。
【问题讨论】:
是的,Array
构造函数很少有用。
【参考方案1】:
所以据我所知,它调用 Array() 就好像它传递了 10 个参数,但由于它没有定义任何这些“整数属性”,就好像它传递了 10 个未定义的参数。对吗?
是的,没错。它正在这样做:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
var barr = new Array(10); console.log(barr);
...
console.log(arr.map(function(item) return 'hi';)); console.log(barr.map(function(item) return 'hi';));
我想知道为什么第二个地图功能不起作用。
因为map
、forEach
和类似的仅访问实际存在的属性。正如你所说,两者之间有很大的不同。
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
// Or `var arr = Array.apply(null, length: 10);
和
var barr = new Array(10);
在第一个示例中,arr
有 10 个条目,每个条目的值都为 undefined
。在第二个示例中,barr
有 没有条目 和 length
的 10
。所以在第一个中,map
将访问这些属性,因为它们存在。在第二个中,它不会,因为他们没有。
回想一下 JavaScript aren't really arrays at all 中的标准数组(披露:这是我博客上的一篇文章),它们是具有一些特殊行为的对象。因此,它们本质上是稀疏的:
var a = [];
a.length = 10000;
a
没有 10,000 个条目。它有 no 个条目。只是它的length
属性是10000
。
您可以使用hasOwnProperty
或in
判断该属性是否存在。比较:
var barr = new Array(10);
console.log(barr.hasOwnProperty(0)); // false
console.log(0 in barr); // false
到:
var arr = Array.apply(null, length: 10);
console.log(arr.hasOwnProperty(0)); // true
console.log(0 in arr); // true
而
Array.apply
之所以有效,是因为它询问length: 10
它的属性0
是什么,接收undefined
,因此将undefined
分配给它正在构造的数组的属性0
,等等。我的推理正确吗?
是的,尽管要清楚,它是 apply
询问 0
是什么属性,然后它在调用 Array
时将其用作第一个参数。然后是Array
,它获取第一个参数的值并将其分配给它正在创建的数组上的0
属性。
真的有没有更骇人听闻的方法来定义一个数组,该数组包含其范围内每个索引的未定义整数属性,而不是根本没有整数属性?
只有一点点:ES2015 添加了Array.from
,它接受一个类似数组的对象并返回一个真正的数组(可选地映射条目)。那就是:
var arr = Array.from(length:10);
很少需要这样做,而不是简单地a = new Array(bigNumberHere);
或a = []; a.length = bigNumberHere
。例如,很多时候您并不关心该属性是否不存在或存在值undefined
。有时你会这样做,但为了让你了解一下,我已经专业地编写 JavaScript 20 年了,在过去的 8 年中相当密集,而且我可能关心过,哦,一次或两次,最重要的。
您提到在您处理的特定情况下,它与map
结合使用,因此Array.from
将代替两者:
var arr = Array.from(length: 10, function() return "hi"; );
...产量
["hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi"]
虽然Array.from
在 ES2015 中是新的,但它可以在旧的 JavaScript 引擎上进行填充/填充。
【讨论】:
在这种特殊情况下,这是因为编码人员继续在同一行使用 map,return Array.apply(null, length: 100).map(function(value, index) ... );
,试图尽可能简洁地编写作为练习。没必要,我同意,但事实证明它很有教育意义。感谢您的帮助!
@PoolOfPeas:有道理。我应该在上面提到Array.from
(现在我有)。 :-)【参考方案2】:
对吗?
是的
你也可以使用任何类型的类似数组的对象,所以在 练习这意味着它将有一个属性长度和整数 范围内的属性(0...长度)。
它说你可以传递一个数组的duck-type:一个具有某种接口的对象:
-
长度属性(用于迭代)
可选:一些整数属性(值)
这将被视为一个数组。 所以传递一个 length: 10 就像传递一个真正的数组 [undefined,undefined,undefined,..] 每个索引都被创建并且具有未定义的值。
所以第一行代码:
var arr = Array.apply(null, length: 10);
被解释为:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
所以我目前的猜测是 arr 是一个包含整数的数组 属性 10 个变量,每个变量的值为 undefined 和 barr 是一个数组,虽然它的长度为 10,但没有整数 属性。
是的。
var test = Array(10);
它输出:[undefined x10]
test[2] = undefined;
它输出:[undefined x2, undefined, undefined x7]
【讨论】:
以上是关于JavaScript 中带有 new Array() 的未定义值的主要内容,如果未能解决你的问题,请参考以下文章
javascript:关于js的function参数中带的Event
JavaScript Array vs new Array区别
在 JavaScript 中,myArray.length = 0 与 myArray = new Array() 有啥区别? [复制]