Array, New Array(), []的区别和使用

如果我们要初始化一个数组,那么我们使用下面的几种方式

var a = Array()

var b = new Array()

var c = []

上面的三行代码都各自创建了一个length=0的JS数组。三者是如何运行的,又各自有什么区别?

new Array()

根据new的规定,new只是一个语法糖。new Array()创建了一个对象,新建的对象a.__proto__ == Array.prototype。这是标准的一个由Class到实例的创建步骤。体现了JS在面向对象方面向主流语言的过度。

Array()

Array()和new Array()完全一致。根据 spec,两者完全一致

When Array is called as a function rather than as a constructor, it creates and initialises a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.

[]

[]也被称为literal syntax,它同样会创建一个空数组。得到的结果和new Array(),以及Array全部一样。

对于究竟应该使用new还是使用{},[],以及function此类的literal syntax。网上的说法不一,具体的可以参考文章后面的链接。在自己实际使用中:

从性能上来讲,new Array() 在初始化大数组的时候,性能更加优异,在之前大数组创建的文章中已经提到了这个内容。当初始化一个空数组时候,两者性能几乎没有差异。因此优先使用Array()或者new Array()

从语言特性上讲,JS是一个基于原型继承的语言。无论是new的引入,以及在ES6中引入的Class语法糖,都是为了将JS进一步向对象化的方向进行过度。虽然使用new,会增加多一层的对象包裹,而使得内存冗余。但使用new后更加符合了对象化继承的概念。自我感觉上,使用new应该是更加好的方式。

在其他文章中,有人提到了使用new来实现对象化的一些问题,比如当使用一个function作为基类的时候。我们可以在调用的时候,不使用new进行调用。比如下面的代码

function foo () {

var name = 'name'

}

foo.prototype.getName = function () { console.log(1) }

var t = foo()

此时t是一个undefined,而不是我们想要的继承getName方法的对象。并且此时JS解释器并不会报错。

为了解决这个问题,可以在function中添加下面的代码:

function foo()

{

// 如果用户没有使用new进行调用则静默调用new

if ( !(this instanceof foo) )

return new foo();

// constructor logic follows...

}

或者更通用的方法

if ( !(this instanceof arguments.callee) ) // 在这里不再使用foo来判定,而是通过callee来进行

throw new Error("Constructor called as a function");

其实,为了改进这个小错误,ES6进一步引入了Class关键字。通过Class创建的对象,在调用的时候,必须使用new。Class依然是一个语法糖。

class Point {

constructor(x, y) {

this.x = x;

this.y = y;

}

toString() {

return '(' + this.x + ', ' + this.y + ')';

}

}

var t = Point() // Uncaught TypeError: Class constructor Point cannot be invoked without 'new'

参考链接:

JS秘密花园

使用new会不会有害处

为什么不要使用new

性能比较1

性能比较2

热门