构造函数中“返回”和“新”的行为

时间:2013-05-21 10:13:10

标签: javascript object

我想知道这两个电话之间的区别是什么:

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

如果ba相同,那怎么可能呢?如果使用new,则应忽略返回值:

function test() {
  return 1;
}

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

1 个答案:

答案 0 :(得分:11)

使用new调用函数时,会创建一个新对象并将其作为this传递给函数。如果函数没有返回任何内容(或返回一个原语),那么传入的新对象就是new表达式的结果。 ,如果函数返回一个对象,则抛弃创建的新对象,该函数返回的对象是new表达式的结果。这在规范的Section 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构造函数的一个特殊功能,由Section 15.4.1覆盖。如果你不通过new调用它们,那么规范会仔细列出每个标准构造函数的作用。行为各不相同。他们中的许多人做类型强制,像Array这样的情侣就像你使用new一样,即使你没有,Date做了一件非常奇怪的事情(给你一个字符串版本的当前日期,基本上是String(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,但他们不能影响字面形式。但我认为这不是你问题的重点。 : - )