2

我想知道这两个电话有什么区别:

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

我试图以这种方式模仿这种行为:

function test() {
  return {x:42};
}

var a = test();
var b = new test();
console.log(a,b); // the same

这怎么可能b是一样的a?如果new使用,则应忽略返回值:

function test() {
  return 1;
}

var a = test();
var b = new test();
console.log(a,b); // 1 test{}
4

1 回答 1

11

当您使用 调用函数时new,会创建一个新对象并将其作为 传递给函数this。如果函数没有返回任何东西(或返回一个原语),那么传入的新对象就是new表达式的结果。但是,如果函数返回一个对象,则创建的新对象将被丢弃,而函数返回的对象是new表达式的结果。这在规范的第 11.2.2 节中的冗长的散文中有所介绍。它对于构造函数维护某种缓存并在参数相同(或者当然是单例)的情况下重用实例的不可变对象最有用。

因此,在您的示例中,由于您的test函数返回一个对象,因此通过new创建并丢弃由new运算符创建的对象来调用它,结果是您从中返回的对象test

如果你返回一个不同的对象,我可能不应该说来自的对象new必然被“丢弃”。构造函数可能会对对象做一些事情,以new防止它被丢弃。例如,您可以编写如下构造函数:

function WeirdConstructor() {
    return {
        theNewObject: this
    };
}

...它获取由创建的对象new并将其作为它返回的对象的属性。将其称为特殊情况是委婉的说法。:-)

Array(1, 2, 3)和都返回一个新数组的事实new Array(1, 2, 3)实际上只是Array构造函数的一个特殊功能,第 15.4.1 节介绍了这一点。如果您不通过new. 行为各不相同。他们中的许多人确实进行了类型强制,一对夫妇就像你没有Array使用过的那样,并且做了一件非常奇怪的事情(给你一个当前日期的字符串版本,基本上)。newDateString(new Date())


具体而言Array:我不会使用Array(1, 2, 3) new Array(1, 2, 3)。我会用[1, 2, 3]. 这不是模棱两可的(new Array(3)创建一个空白数组length = 3或一个包含一个条目的数组,3, 在其中?那new Array("3")呢?),并且有可能(尽管不太可能)有人可以遮蔽符号Array,但他们不能遮蔽文字形式。但我认为这不是你问题的重点。:-)

于 2013-05-21T10:15:32.650 回答