我想知道这两个电话之间的区别是什么:
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{}
答案 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
,但他们不能影响字面形式。但我认为这不是你问题的重点。 : - )