通过只添加元素而不添加推送javascript来更改数组大小

通过只添加元素而不添加推送javascript来更改数组大小,javascript,angularjs,Javascript,Angularjs,我知道更改数组大小的通用方法是使用.push() 然而,今天我在angularJS中看到了一段代码,它的功能如下: var service = { pages: [], doSmth: doSmth }; doSmth(); function doSmth() { service.pages[1] = "abc"; service.pages[5] = "def"; } 我在浏览器上运行了调试器,发现在调用doSmth()之前,pages[1]是未定义的,但是在这之

我知道更改数组大小的通用方法是使用
.push()

然而,今天我在angularJS中看到了一段代码,它的功能如下:

var service = {
   pages: [],
   doSmth: doSmth
};

doSmth();

function doSmth() {
   service.pages[1] = "abc";
   service.pages[5] = "def";
}
我在浏览器上运行了调试器,发现在调用
doSmth()
之前,
pages[1]
是未定义的,但是在这之后,
pages[1]
被赋值,没有任何错误


这怎么可能呢?

JavaScript中的数组只是一个具有某些特殊属性的对象。本质上,它们只是具有正整数属性名的对象。还有一些其他的关键区别,但想法是你可以做到这一点:

var obj = { };
obj['1'] = 'abc';
因此,可以对数组执行相同的操作


然而!你不应该。现代JavaScript引擎通常通过使用快速的本机实现支持数组来优化数组。通过设置当前未分配的索引,您的代码将被反优化为更像对象的内容,速度会慢得多。
函数doSmth()
中的页面与
服务中的页面不在同一命名空间中,即
服务.Pages

您的
页面[1]
不能在其他地方声明为全局

但是,您正在将
页面
初始化为空(但现有)数组:
页面:[],

var service = {
    pages: [],
    doSmth: doSmth
};

doSmth();

function doSmth() {
    pages[1] = "abc";
    pages[5] = "def";
}

这就是JavaScript所允许的魔力。如果您来自Java或C之类的语言,这似乎是一个奇怪的想法,但是您可以随时设置数组中任何索引的值,数组将扩展到该大小

考虑:

var t = [];
t.length === 0;
t[10000] = 'value';
t.length === 10001;
JavaScript只是在幕后处理这个问题。值得一提的是,这种行为并非特定于JavaScript。在其他解释语言中也可以看到这一点。例如,Ruby允许您做同样的事情

此外,在JavaScript中,
length
是数组的可写属性,因此您可以轻松地截断或清除整个数组:

var t = [1];
t[4] = 0;
t === [1, undefined, undefined, undefined, 0];
t.length = 2;
t === [1, undefined];
t.length = 0;
t === [];

将长度设置为0是清除数组的最快、最简单的方法之一。这可能不是最直观的解决方案,但我会选择它。

因为页面已在页面中初始化:[]。如果没有页面:[],您将看到未定义的错误。将值指定给等于或超过数组长度的索引将调整其大小以适应。您预期的行为是什么?请记住,
函数doSmth
已被提升。您始终可以在任何索引处向数组添加一个元素,它将“调整大小”(只要长度看起来是最大的索引+1),以适应需要。
push
函数只是方便地向
myarray[myarray.length]
@PTN添加一个元素:Javascript中没有OutOfBounds@编码员:以什么方式?@minitech看到我的答案了,它不一样namespace@tanjir,我理解,数组只是专门的JS对象。我正在演示如何在对象上设置任何属性的基本方法。我最喜欢Brennans anwer解释额外的魔法。注意:阵列可能不会实际扩展。它的行为就好像是这样,但在内部,根据实现的不同,它很可能没有实际分配任何额外的空间。所有这些都在规范中进行了正式描述