构造函数可以返回什么值来避免返回?
当使用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]]
属性时,将执行以下步骤:
- 创build一个新的本机ECMAScript对象。
- 将
Result(1)
的[[Class]]
属性设置为"Object"
。- 获取
F
的prototype属性的值。- 如果
Result(3)
是一个对象,则将Result(1)
的[[Prototype]]
属性设置为Result(3)
。- 如果
Result(3)
不是一个对象,则按照15.2.3.1的描述将Result(1)
的[[Prototype]]
属性设置为原始的Object
原型对象。- 调用
F
的[[Call]]
属性,将Result(1)
作为this
值,并将传递给[[Construct]]
的参数列表作为参数值。- 如果
Type (Result(6))
是Object
则返回Result(6)
。- 返回
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,就像在函数被调用之前那样。