What’s the difference between “Array()” and “[]” while declaring a JavaScript array?
声明这样的数组的真正区别是什么:
1 | var myArray = new Array(); |
和
1 | var myArray = []; |
有区别,但在那个例子中没有区别。
使用更详细的方法:
1 2 | x = new Array(5); alert(x.length); // 5 |
要说明创建数组的不同方法:
1 2 3 4 5 6 7 8 9 10 11 | var a = [], // these are the same b = new Array(), // a and b are arrays with length 0 c = ['foo', 'bar'], // these are the same d = new Array('foo', 'bar'), // c and d are arrays with 2 strings // these are different: e = [3] // e.length == 1, e[0] == 3 f = new Array(3), // f.length == 3, f[0] == undefined ; |
使用隐式数组创建数组和使用数组构造函数创建数组之间的区别是微妙的,但很重要。
当使用
1 | var a = []; |
您要告诉解释器创建一个新的运行时数组。根本不需要额外的处理。完成。
如果使用:
1 | var a = new Array(); |
您要告诉解释器,我想调用构造函数"
你可能会想,"好吧,这一点都不重要。他们是一样的!"很遗憾,你不能保证。
举个例子:
1 2 3 4 5 6 7 8 9 10 11 | function Array() { this.is = 'SPARTA'; } var a = new Array(); var b = []; alert(a.is); // => 'SPARTA' alert(b.is); // => undefined a.push('Woa'); // => TypeError: a.push is not a function b.push('Woa'); // => 1 (OK) |
在上面的示例中,第一个调用将如您所期望的那样警告"sparta"。第二个不会。你最终会发现未定义。您还将注意到,b包含所有本机数组对象函数,如
虽然您可能希望发生这种情况,但它只是说明了这样一个事实:
如果您知道您只需要一个数组,那么最好使用
有一个巨大的差异,没有人提到。
你可能认为
1 2 3 | new Array(2).length // 2 new Array(2)[0] === undefined // true new Array(2)[1] === undefined // true |
但它不是!
让我们试试
1 2 | [undefined, undefined].map(e => 1) // [1, 1] new Array(2).map(e => 1) //"(2) [undefined × 2]" in Chrome |
看到了吗?不一样!但为什么呢?
根据ES6规范22.1.1.2,
根据规范22.1.3.15,函数
1 2 | new Array(2).hasOwnProperty(0) // false [undefined, undefined].hasOwnProperty(0) // true |
这就是为什么您不能期望任何迭代函数像往常一样工作于从
btw、safari和firefox对此有更好的表达:
1 2 3 4 5 6 7 8 9 | // Safari new Array(2) // [](2) new Array(2).map(e => 1) // [](2) [undefined, undefined] // [undefined, undefined] (2) // Firefox new Array(2) // Array [ <2 empty slots> ] new Array(2).map(e => 1) // Array [ <2 empty slots> ] [undefined, undefined] // Array [ undefined, undefined ] |
我已经向Chrome提交了一个问题,要求他们修复这个令人困惑的日志:https://bugs.chromium.org/p/chromium/issues/detail?ID=732021
更新:已经修复。Chrome现在登录为
1 | new Array(2) // (2) [empty × 2] |
奇怪的是,
更准确地说:
有关更多信息,下面的页面描述了为什么不需要使用
You never need to use
new Object() in
JavaScript. Use the object literal{}
instead. Similarly, don’t usenew Array() ,
use the array literal[]
instead. Arrays in JavaScript work
nothing like the arrays in Java, and
use of the Java-like syntax will
confuse you.Do not use
new Number ,new String , or
new Boolean . These forms produce
unnecessary object wrappers. Just use
simple literals instead.
还可以查看注释-
为了更好地理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | > [] [] > new Array() [] > [] == [] false > [] === [] false > new Array() == new Array() false > new Array() === new Array() false > typeof ([]) "object" > typeof (new Array()) "object" > [] === new Array() false > [] == new Array() false |
以上结果来自Windows7上的GoogleChrome控制台。
第一个是默认的对象构造函数调用。如果需要,可以使用它的参数。
1 | var array = new Array(5); //initialize with default length 5 |
第二种方法使您能够创建非空数组:
1 | var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3. |
我可以用更具体的方式来解释,从这个基于弗雷德里克的好例子开始。
1 2 3 4 5 6 7 8 9 10 11 12 | var test1 = []; test1.push("value"); test1.push("value2"); var test2 = new Array(); test2.push("value"); test2.push("value2"); alert(test1); alert(test2); alert(test1 == test2); alert(test1.value == test2.value); |
我刚刚为数组添加了另一个值,并发出了四个警报:第一个和第二个是给我们每个数组中存储的值,以确定这些值。他们也会回来的!现在试试第三个,它返回错误,那是因为
JS treats test1 as a VARIABLE with a data type of array, and it treats test2 as an OBJECT with the functionality of an array, and
there are few slight differences here.
第一个不同点是,当我们调用test1时,它调用一个变量而不进行思考,它只返回存储在这个变量中的值,而不考虑它的数据类型!但是,当我们调用test2时,它调用array()函数,然后将我们的"pushed"值存储在它的"value"属性中,当我们通知test2时,它也会返回array对象的"value"属性。
因此,当我们检查test1是否等于test2时,它们当然不会返回true,一个是函数,另一个是变量(带有数组类型),即使它们具有相同的值!
要确定这一点,请尝试添加.value的第四个警报;它将返回true。在这种情况下,我们告诉JS"不管容器的类型是函数还是变量,请比较存储在每个容器中的值,并告诉我们您看到了什么!"事情就是这样。
我希望我清楚地说出了背后的想法,并为我糟糕的英语道歉。
没有什么大的区别,他们基本上做相同的事情,但是以不同的方式做,但是继续阅读,看看W3C上的这个声明:
1 | var cars = ["Saab","Volvo","BMW"]; |
和
1 | var cars = new Array("Saab","Volvo","BMW"); |
The two examples above do exactly the same. There is no need to use
new Array(). For simplicity, readability and execution speed, use the
first one (the array literal method).
但同时,使用
Avoid new Array()
There is no need to use the JavaScript's built-in array constructor
new Array().
Use [] instead.
These two different statements both create a new empty array named
points:
1 2 | var points = new Array(); // Bad var points = []; // Good |
These two different statements both create a new array containing 6
numbers:
1 2 | var points = new Array(40, 100, 1, 5, 25, 10); // Bad var points = [40, 100, 1, 5, 25, 10]; // Good |
The new keyword only complicates the code. It can also produce some
unexpected results:
1 | var points = new Array(40, 100); // Creates an array with two elements (40 and 100) |
What if I remove one of the elements?
1 | var points = new Array(40); // Creates an array with 40 undefined elements !!!!! |
所以基本上不认为是最佳实践,也有一个小的区别,你可以这样把长度传递给
第一个是默认的对象构造函数调用。主要用于动态值。
1 | var array = new Array(length); //initialize with default length |
创建静态值时使用第二个数组
1 | var array = [red, green, blue, yellow, white]; // this array will contain values. |
我用[]犯了一个奇怪的行为。
我们有模型"类",其中的字段初始化为某个值。例如。:
1 2 3 4 5 6 7 8 9 10 11 12 | require([ "dojo/_base/declare", "dijit/_WidgetBase", ], function(declare, parser, ready, _WidgetBase){ declare("MyWidget", [_WidgetBase], { field1: [], field2:"", function1: function(), function2: function() }); }); |
我发现当用
这不会用
我不确定我们使用的框架(dojo)是否有问题。
如我所知,差异U可以找到切片(或数组的其他功能),如code1。code2显示U数组及其实例:
代码1:
1 2 3 4 | [].slice; // find slice here var arr = new Array(); arr.slice // find slice here Array.prototype.slice // find slice here |
代码2:
1 2 3 | [].__proto__ == Array.prototype; // true var arr = new Array(); arr.__proto__ == Array.prototype; // true |
结论:
如你所见,
它们只是数组的不同实例。
:)
使用的差异
1 | var arr = new Array(size); |
或
1 2 | arr = []; arr.length = size; |
在这个问题上讨论得够多了。
我想补充一下速度问题——目前最快的方法,在
但是请注意,这些事情往往会随着更新而改变很多。另外,不同浏览器的运行时间也不同。
例如,我提到的第二个选项,在
不管怎样,我建议你每隔一段时间在不同的浏览器(和机器)上查看一次,像这样使用站点
初始化没有任何长度的数组时没有区别。因此,
但是,如果用长度像
每当您执行array_object.push时,它会在最后一个元素后添加项并增加长度,这将是一个问题。
1 2 3 | var b = new Array(1); b.push("hello world"); console.log(b.length); // print 2 |
VS
1 2 3 | var v = []; a.push("hello world"); console.log(b.length); // print 1 |
我发现这两种结构有一个不同之处,那就是咬得我很厉害。
假设我有:
1 2 3 4 5 6 | function MyClass(){ this.property1=[]; this.property2=new Array(); }; var MyObject1=new MyClass(); var MyObject2=new MyClass(); |
在现实生活中,如果我这样做:
1 2 3 4 | MyObject1.property1.push('a'); MyObject1.property2.push('b'); MyObject2.property1.push('c'); MyObject2.property2.push('d'); |
我最后得出的结论是:
1 2 3 4 | MyObject1.property1=['a','c'] MyObject1.property2=['b'] MyObject2.property1=['a','c'] MyObject2.property2=['d'] |
我不知道语言规范所说的应该发生什么,但是如果我希望我的两个对象在我的对象中有唯一的属性数组,我必须使用
使用数组构造函数生成一个所需长度的新数组,并用未定义的索引填充每个索引,将数组分配给一个变量将创建您为其提供信息的索引。