使用JavaScript

时间:2016-01-30 09:52:16

标签: javascript arrays properties

看一些javascript代码,我看到了(像这样):

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

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

  

你也可以使用类似于数组的任何类型的对象,所以在实践中这意味着它将具有属性长度和范围内的整数属性(0 ...长度)。

所以从我所知道的,它调用Array()好像它传递了10个参数,但由于它没有定义任何这些“整数属性”,所以就好像传递了10个未定义的参数一样。 这是正确的吗?

console.log(arr);

产量

  

[未定义,     不确定的,     不确定的,     不确定的,     不确定的,     不确定的,     不确定的,     不确定的,     不确定的,     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';}));

给出

  

['hi','hi','hi','hi','hi','hi','hi','hi','hi','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()很没用。

2 个答案:

答案 0 :(得分:5)

  

从我所知道的,它调用Array()就像传递了10个参数一样,但由于它没有定义任何"整数属性",它&& #39; s好像它传递了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包含没有条目length 10。因此,在第一个中,map将访问属性,因为它们存在。在第二个中,它不会,因为他们不会。

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

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

a没有10,000个条目。它有没有条目。它的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属性。

  

对于定义一个包含其范围内每个索引的未定义整数属性的数组,而不是根本没有整数属性,是否真的没有简单的hackish方式?

仅轻微:ES2015添加Array.from,它接受​​类似数组的对象并返回一个真实数组(可选择映射条目)。那就是:

var arr = Array.from({length:10});

与简单a = new Array(bigNumberHere);a = []; a.length = bigNumberHere相反,这种情况很少见。例如,如果财产不存在或存在价值undefined,您很多时候都不在乎。有时你这样做,但是为了给你提供观点,我已经专业地编写了20年的JavaScript,在过去的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引擎上进行填充/填充。

答案 1 :(得分:1)

  

这是对的吗?

  

你也可以使用任何类似于数组的对象,所以   实践这意味着它将具有属性长度和整数   范围内的属性(0 ...长度)。

它表示您可以传递数组的 duck-type :具有某种接口的对象:

  1. 长度属性(用于迭代)
  2. 可选:一些整数属性(值)
  3. 这将被视为一个数组。 所以传递一个{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]< - 没有索引,除了位置' 2'有一个值:undefined。