Javascript 构造函数可以返回哪些值以避免返回 this?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1978049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What values can a constructor return to avoid returning this?
提问by Thomas Eding
What are the exact circumstances for which a returnstatement in Javascript can return a value other than thiswhen a constructor is invoked using the newkeyword?
return除了this使用new关键字调用构造函数时,Javascript中的语句可以返回值的确切情况是什么?
Example:
例子:
function Foo () {
return something;
}
var foo = new Foo ();
If I'm not mistaken, if somethingis a non-function primitive, thiswill be returned. Otherwise somethingis returned. Is this correct?
如果我没记错的话,ifsomething是一个非函数原语,this会被返回。否则something返回。这样对吗?
In other words, what values can somethingtake to cause (new Foo () instanceof Foo) === false?
换句话说,什么值可以something导致(new Foo () instanceof Foo) === false?
回答by CMS
The exact condition is described on the [[Construct]]internal property, which is used by the newoperator:
操作符[[Construct]]使用的内部属性描述了确切的条件new:
From the ECMA-262 3rd. Edition Specification:
来自 ECMA-262 3rd。版本规格:
13.2.2
[[Construct]]When the
[[Construct]]property for aFunctionobjectFis called, the following steps are taken:
- Create a new native ECMAScript object.
- Set the
[[Class]]property ofResult(1)to"Object".- Get the value of the prototype property of
F.- If
Result(3)is an object, set the[[Prototype]]property ofResult(1)toResult(3).- If
Result(3)is not an object, set the[[Prototype]]property ofResult(1)to the originalObjectprototype object as described in 15.2.3.1.- Invoke the
[[Call]]property ofF, providingResult(1)as thethisvalue and providing the argument list passed into[[Construct]]as the argument values.- If
Type(Result(6))isObjectthen returnResult(6).- Return
Result(1).
13.2.2
[[Construct]]调用对象的
[[Construct]]属性时,将执行以下步骤:FunctionF
- 创建一个新的原生 ECMAScript 对象。
- 将 的
[[Class]]属性设置Result(1)为"Object"。- 获取 的原型属性的值
F。- 如果
Result(3)是对象,则将 的[[Prototype]]属性设置Result(1)为Result(3)。- 如果
Result(3)不是对象,则将 的[[Prototype]]属性设置Result(1)为原始Object原型对象,如15.2.3.1 中所述。- 调用 的
[[Call]]属性F,提供Result(1)作为this值并提供[[Construct]]作为参数值传入的参数列表。- 如果
Type(Result(6))是Object然后返回Result(6)。- 返回
Result(1)。
Look at steps 7 and 8, the new object will be returned only if the
type of Result(6)(the value returned from the Fconstructor
function) is notan Object.
看第 7 步和第 8 步,只有在类型Result(6)(F构造函数返回的值)不是Object 时,才会返回新对象。
回答by philn5d
Concrete examples http://jsbin.com/zivivucahi/1/edit?html,js,console,output
具体例子 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('%')));
回答by mkrause
I couldn't find any documentation on the matter, but I think you're correct. For example, you can return new Number(5)from a constructor, but not the literal 5(which is ignored and thisis returned instead).
我找不到有关此事的任何文件,但我认为您是对的。例如,您可以new Number(5)从构造函数返回,但不能从文字返回5(它被忽略并this返回)。
回答by Ravindra Thorat
Trying to put a few points in simpler words.
试图用更简单的词来表达几点。
In javascript, when you use a newkeyword on a function and if,
在 javascript 中,当您new在函数上使用关键字时,如果,
- function does not return anything, it will return an intended object
- 函数不返回任何东西,它将返回一个预期的对象
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
- function returns any truthycomplex object [object, array, function etc], that complex object takes priority and
uservariable will hold the returned complex object
- 函数返回任何真实的复杂对象[对象、数组、函数等],该复杂对象优先,
user变量将保存返回的复杂对象
function User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
- function returns any literal, constructor takes priority and it will return an intended object
- 函数返回任何文字,构造函数优先,它将返回一个预期的对象
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
回答by Camilo Martin
As a side note, the return value or thisis just part of the equation.
作为旁注,返回值 orthis只是等式的一部分。
For example, consider 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'
As you can see, .valueOf()is internally used and can be exploited for fun and profit. You can even create side effects, for example:
如您所见,.valueOf()在内部使用,可以被利用以获取乐趣和利润。您甚至可以创建副作用,例如:
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
I can imagine this must have somesort of practical application. And it doesn't have to be explicitly a Numbereither, if you add .valueOfto any object it can behave as a number:
我能想象这必须有某种类型的实际应用。而且它也不必明确是 a Number,如果您添加.valueOf到任何对象,它可以表现为一个数字:
({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
You can exploit this to make an object that always returns a new GUID, for instance.
例如,您可以利用它来创建一个始终返回新 GUID 的对象。
回答by Guffa
When you are using the newkeyword, an object is created. Then the function is called to initialise the object.
使用new关键字时,将创建一个对象。然后调用函数来初始化对象。
There is nothing that the function can do to prevent the object being created, as that is done before the function is called.
函数无法阻止创建对象,就像在调用函数之前那样。

