构造函数可以返回什么值来避免返回?

当使用new关键字调用构造函数时,Javascript中的return语句可以返回非this值的确切情况是什么?

例:

 function Foo () { return something; } var foo = new Foo (); 

如果我没有弄错,如果something是一个非函数原语,就会返回。 否则返回something 。 它是否正确?

IOW,什么值可以引起(new Foo () instanceof Foo) === false

确切的条件在new操作符使用的[[Construct]]内部属性中描述:

来自ECMA-262第3名。 版本规格:

13.2.2 [[Construct]]

当调用Function对象F[[Construct]]属性时,将执行以下步骤:

  1. 创build一个新的本机ECMAScript对象。
  2. Result(1)[[Class]]属性设置为"Object"
  3. 获取F的prototype属性的值。
  4. 如果Result(3)是一个对象,则将Result(1)[[Prototype]]属性设置为Result(3)
  5. 如果Result(3)不是一个对象,则按照15.2.3.1的描述将Result(1)[[Prototype]]属性设置为原始的Object原型对象。
  6. 调用F[[Call]]属性,将Result(1)作为this值,并将传递给[[Construct]]的参数列表作为参数值。
  7. 如果Type (Result(6))Object则返回Result(6)
  8. 返回Result(1)

看第7步和第8步,只有Result(6)的typesResult(6)F构造函数返回的值) 不是 Object时,才会返回新的对象。

我找不到关于此事的任何文件,但我认为你是正确的。 例如,您可以从构造函数中返回new Number(5) ,但不是文字5 (它被忽略,而是返回)。

具体的例子http://jsbin.com/zivivucahi/1/edit?html,js,console,output

 /* ECMA 262 v 5 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf "4.3.2 primitive value member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6" */ var Person = function(x){ return x; }; console.log(Person.constructor); console.log(Person.prototype.constructor); console.log(typeof(Person)); console.log(typeof(Person.prototype)); function log(x){ console.log(x instanceof Person); console.log(typeof x); console.log(typeof x.prototype); } log(new Person(undefined)); log(new Person(null)); log(new Person(true)); log(new Person(2)); log(new Person("")); //returns a function not an object log(new Person(function(){})); //implementation? //log(new Person(Symbol('%'))); 

作为一个侧面说明,返回值或者this只是等式的一部分。

例如,考虑一下:

 function Two() { return new Number(2); } var two = new Two; two + 2; // 4 two.valueOf = function() { return 3; } two + 2; // 5 two.valueOf = function() { return '2'; } two + 2; // '22' 

正如你所看到的, .valueOf()在内部使用,可以被利用的乐趣和利润。 您甚至可以创build副作用,例如:

 function AutoIncrementingNumber(start) { var n = new Number, val = start || 0; n.valueOf = function() { return val++; }; return n; } var auto = new AutoIncrementingNumber(42); auto + 1; // 43 auto + 1; // 44 auto + 1; // 45 

我可以想象这必须有某种实际应用。 而且它不一定是一个Number ,如果将.valueOf添加到任何对象,它可以performance为一个数字:

 ({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638 

例如,你可以利用这个来创build一个总是返回一个新的GUID的对象。

当您使用new关键字时,会创build一个对象。 然后调用该函数来初始化该对象。

这个函数没有任何东西可以阻止对象被创build,就像在函数被调用之前那样。