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';));

我想知道为什么第二个地图功能不起作用。

因为mapforEach 和类似的仅访问实际存在的属性。正如你所说,两者之间有很大的不同。

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没有条目length10。所以在第一个中,map 将访问这些属性,因为它们存在。在第二个中,它不会,因为他们没有。

回想一下 JavaScript aren't really arrays at all 中的标准数组(披露:这是我博客上的一篇文章),它们是具有一些特殊行为的对象。因此,它们本质上是稀疏的

var a = [];
a.length = 10000;

a 没有 10,000 个条目。它有 no 个条目。只是它的length属性是10000

您可以使用hasOwnPropertyin 判断该属性是否存在。比较:

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中带有一个数字的数组映射[重复]

javascript:关于js的function参数中带的Event

JavaScript Array vs new Array区别

在 JavaScript 中,myArray.length = 0 与 myArray = new Array() 有啥区别? [复制]

JavaScript 中“new Array(..)”和“[..]”的区别? [复制]

将特定数组元素与C中带有“if”的字符串进行比较?