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

Jan*_*roň 2 javascript object

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

var a = Array(1,2,3);
var b = new Array(1,2,3);
Run Code Online (Sandbox Code Playgroud)

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

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

var a = test();
var b = new test();
console.log(a,b); // the same
Run Code Online (Sandbox Code Playgroud)

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

function test() {
  return 1;
}

var a = test();
var b = new test();
console.log(a,b); // 1 test{}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 11

使用函数调用函数时new,会创建一个新对象并将其作为函数传递给函数this.如果函数没有返回任何内容(或返回一个原语),那么传入的新对象就是new表达式的结果.但是,如果函数返回一个对象,则抛弃创建的新对象,并且该函数返回的对象是new表达式的结果.这在规范的第11.2.2节中的turgid散文中有所涉及.它对于不可变对象非常有用,其中构造函数维护某种缓存并在参数相同(或者当然是单例)时重用实例.

所以在你的例子中,因为你的test函数返回一个对象,new只需创建并抛弃new操作符创建的对象,结果就是你要返回的对象test.

new如果你返回一个不同的对象,我可能不应该说对象必然会被"抛弃".构造函数可以对该对象执行某些操作,以new防止它被丢弃.例如,您可以编写如下构造函数:

function WeirdConstructor() {
    return {
        theNewObject: this
    };
}
Run Code Online (Sandbox Code Playgroud)

...获取由其创建的对象new并使其成为它返回的对象的属性.称之为特殊情况就是温和地说.:-)

这样的事实Array(1, 2, 3),并new Array(1, 2, 3)都返回一个新的数组实际上是只是一种特殊的功能Array构造,所涵盖的第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,但它们不能遮蔽文字形式.但我认为这不是你问题的重点.:-)