在JavaScript中,Array(1)和new Array(1)有什么区别?

50

我刚开始思考这个问题,但是在 jsFiddle 中试着操作时并没有发现任何不同之处。

var a = new Array(1),
    b = Array(1);

console.log(a, b);

输出是两个数组,其中一个成员未定义。

使用for (in)循环可以发现它们具有相同的属性。

这两者之间有什么区别?第一个是否只是显式地实例化对象?

请不要就使用数组字面量符号对我进行讲解,因为我已经知道这一点。我更希望填补上述知识空白。


1
JS 中的 new 关键字 - Jonathon Faust
我要大胆猜测一下,new 的意思是它是一个对象,而没有 new 的不是。有 new 的那个将会有如此描述的方法 http://www.w3schools.com/jsref/jsref_obj_array.asp,而没有 new 的则没有。 - Flipper
@Flipper 我遍历了每个属性,它们似乎都有相同的方法。 - alex
@alex 是的,我刚刚也做了同样的事情,没有发现任何区别。这就是为什么我只留下了评论而不是答案的原因。不过问题值得点赞! - Flipper
看起来将Array()作为函数调用也会返回一个数组对象,就像调用new Array()一样。 - Max
4个回答

56

使用 Array,这两种方式是等效的。当作为函数调用时,new 会被自动注入:

15.4.1 作为函数调用的 Array 构造函数

Array 被作为函数而非构造函数调用时,它会创建并初始化一个新的 Array 对象。因此函数调用 Array(…) 等同于带有相同参数的对象创建表达式 new Array(…)

摘自 ECMA-262 第三版(类似内容可见于 第五版)。也请参考 ECMA-262 ECMAScript 2020 规范(第十一版)中的 22.1.1 Array 构造函数


9
根据《JavaScript权威指南》第5版第602页的描述,“当以函数形式调用Array()构造函数时,没有使用new运算符,它的行为与使用new运算符时完全相同。”

5

区别在于Array函数的实现方式。如果调用Array函数时没有使用new运算符,则返回一个Array实例的行为取决于具体的实现。例如,Mozilla的SpiderMonkey引擎会执行以下操作:

static JSBool
Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
     jsuint length;
     jsval *vector;

     /* If called without new, replace obj with a new Array object. */

这是实际来源的实际评论。下面的代码行没有重现在这里。我想其他引擎也是这样做的。否则,行为未定义。关于这个话题的好读物是John Resig的帖子这里


John Resig的帖子是关于用户定义函数的。没有使用newArray的行为在ECMA规范中有明确定义,正如其他答案所描述的那样。 - ZachB

1

new 创建一个新的对象(类实例),并将其作为 this 传递给构造函数。但是,一些函数会检测它们是否使用了 new 并且会像使用了 new 一样运行。其中之一是 Array,因此没有任何区别。

如果您想自己创建这样的构造函数,可以像以下代码一样进行:

function Smth(val) {
  if (!(this instanceof Smth)) {
    return new Smth(val);
  }

  this.val = val;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接