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

2018-12-11  本文已影响0人  安静的牛蛙

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

var a = Array()
var b = new Array()
var c = []

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

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.

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

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

上一篇下一篇

猜你喜欢

热点阅读