美文网首页
Array, New Array(), []的区别和使用

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

作者: 安静的牛蛙 | 来源:发表于2018-12-11 11:48 被阅读0次

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

    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。网上的说法不一,具体的可以参考文章后面的链接。在自己实际使用中:

    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

    相关文章

      网友评论

          本文标题:Array, New Array(), []的区别和使用

          本文链接:https://www.haomeiwen.com/subject/npzlcqtx.html