javascript - JavaScript 中 new Array() 的未定义值

标签 javascript arrays properties

查看一些 javascript 代码,我看到了(类似于)这个:

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

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

you can also use any kind of object which is array-like, so in practice this means it's going to have a property length and integer properties in the range (0...length).

据我所知,它调用 Array() 时就好像它传递了 10 个参数,但由于它没有定义任何这些“整数属性”,它就好像它传递了 10 个未定义的参数。 对吗?

console.log(arr);

产量

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

给予

[ 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi' ]

[ , , , , , , , , , ]

我想知道为什么 map 功能对第二个不起作用。所以我检查了 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() 一点用都没有。

最佳答案

So from what I could tell, it's calling Array() as if it was passed 10 arguments, but since it doesn't define any of those "integer properties", it's as if it was passed 10 undefined arguments. Is that correct?

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

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

I wanted to know why the map function didn't work for the second one.

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

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

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

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

And Array.apply works because it asks {length: 10} what its property 0 is, receives undefined, and so assigns undefined to the property 0 of the array it's constructing, and so on. Is my reasoning correct?

是的,尽管要清楚,它是apply那是在问什么属性0是,然后它在调用 Array 时将其用作第一个参数.这是Array然后获取第一个参数的值并将其分配给 0它正在创建的数组的属性。

And is there really no less hackish way to define an array which contains undefined integer properties for each index within its range, rather than having no integer properties at all?

只有一点点: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 引擎上填充/填充。

关于javascript - JavaScript 中 new Array() 的未定义值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35100285/

相关文章:

c# - 字段依赖属性

javascript - 如何使用 React Link 组件替换字符串的一部分

javascript - 如何在 json 响应返回之前停止 Javascript 表单验证提交?

C# - 在 for 循环中使用相同列表大小的索引位于数组边界之外

c# - 用于快速属性分配的 Visual Studio 快捷方式/语法

java - 在 liferays 留言板中打开验证码

javascript - 如何配置craco使用jsx?

javascript - 如何将一个指令的属性值放入AngularJS中的另一个指令中?

c - 灵活数组成员的使用无效(与其他人不同)

c - 数组大小在运行时确定