JavaScript中带有新数组()的未定义值

JavaScript中带有新数组()的未定义值,javascript,arrays,properties,Javascript,Arrays,Properties,查看一些javascript代码,我看到(类似)如下: 通过阅读Function.prototype.apply()的MDN文档,我了解到,尽管它通常期望一个数组作为其第二个参数,即传递给被调用函数的参数数组 您还可以使用任何类型的类似数组的对象,因此在实践中,这意味着它的属性长度和整数属性的范围为(0…length) 所以从我所知道的,它调用Array()就像传递了10个参数一样,但是因为它没有定义任何“整数属性”,它就像传递了10个未定义的参数一样对吗? console.log(arr);

查看一些javascript代码,我看到(类似)如下:

通过阅读Function.prototype.apply()的MDN文档,我了解到,尽管它通常期望一个数组作为其第二个参数,即传递给被调用函数的参数数组

您还可以使用任何类型的类似数组的对象,因此在实践中,这意味着它的属性长度和整数属性的范围为(0…length)

所以从我所知道的,它调用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';}));
给予

[“嗨”、“嗨”、“嗨”、“嗨”、“嗨”、“嗨”、“嗨”、“嗨”、“嗨”、“嗨”、“嗨”]

[,,,,,]

我想知道为什么map函数对第二个不起作用。所以我检查了
console.log(arr中的1)给出true和“console.log(1 in barr);”这是假的

因此,我目前的猜测是,arr是一个数组,它包含10个变量作为整数属性,每个变量的值为undefined,而barr是一个数组,虽然它的长度为10,但没有整数属性。而Array.apply之所以有效,是因为它询问{length:10}它的属性0是什么,接收未定义的,然后将未定义的赋值给它正在构造的数组的属性0,依此类推。我的推理正确吗?对于定义一个数组,它包含其范围内每个索引的未定义的整数属性,而不是一点整数属性都没有,真的没有比这更简单的方法吗?因为在我看来,
newarray()

所以从我所知道的,它调用Array()就像传递了10个参数一样,但是因为它没有定义任何“整数属性”,它就像传递了10个未定义的参数一样。对吗

是的,没错。它正在这样做:

var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);

console.log(arr.map(function(item) { return 'hi';}));
console.log(barr.map(function(item) { return 'hi';}));
我想知道为什么map函数对第二个不起作用

因为
map
forEach
,以及类似的只访问实际存在的属性。正如你所说,两者之间有很大的区别

var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
// Or `var arr = Array.apply(null, {length: 10});

在第一个示例中,
arr
有10个条目,每个条目都有值
undefined
。在第二个示例中,
barr
没有条目,并且
长度
10
。因此在第一个中,
map
将访问属性,因为它们存在。在第二种情况下,它不会,因为它们不会

回想一下JavaScript中的标准数组(公开:这是我博客上的一篇文章),它们是具有一些特殊行为的对象。因此,它们本质上是稀疏的:

a
没有10000个条目。它没有条目。只是它的
length
属性是
10000

您可以使用
hasOwnProperty
中的
来判断该属性是否存在。比较:

var barr = new Array(10);
console.log(barr.hasOwnProperty(0)); // false
console.log(0 in barr);              // false
致:

Array.apply
工作是因为它询问
{length:10}
它的属性
0
是什么,接收
未定义的
,然后将
未定义的
分配给它正在构造的数组的属性
0
,依此类推。我的推理正确吗

是的,不过要清楚,是
apply
询问
0
是什么属性,然后在调用
Array
时将其作为第一个参数。然后是
Array
获取第一个参数的值,并将其分配给它所创建的数组上的
0
属性

对于定义一个数组,它包含其范围内每个索引的未定义的整数属性,而不是一点整数属性都没有,真的没有比这更简单的方法吗

仅略微增加:ES2015添加了
Array.from
,它接受类似于数组的对象并返回一个真实数组(可选地映射条目)。这就是:

var arr = Array.from({length:10});
很少需要这样做,而不是简单地
a=newarray(bignumberher)
a=[];a、 长度=bignumberher
。例如,很多时候,您不关心该属性是否不存在或是否存在值
未定义的属性。有时候你会这样做,但为了给你一个视角,我已经专业地编写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"]
虽然ES2015中新增了
Array.from
,但它可以在旧的JavaScript引擎上填充

对吗

您还可以使用任何类似数组的对象,因此在 实践这意味着它将有一个属性length和integer 范围(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个变量,每个变量的值为未定义和 barr是一个数组,虽然它有
    var arr = Array.from({length:10});
    
    var arr = Array.from({length: 10}, function() { return "hi"; });
    
    ["hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi"]
    
    var arr = Array.apply(null, {length: 10});
    
    var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)