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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:12:40  来源:igfitidea点击:

What values can a constructor return to avoid returning this?

javascriptconstructornew-operator

提问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 a Functionobject Fis called, the following steps are taken:

  1. Create a new native ECMAScript object.
  2. Set the [[Class]]property of Result(1)to "Object".
  3. Get the value of the prototype property of F.
  4. If Result(3)is an object, set the [[Prototype]]property of Result(1)to Result(3).
  5. If Result(3)is not an object, set the [[Prototype]]property of Result(1)to the original Objectprototype object as described in 15.2.3.1.
  6. Invoke the [[Call]]property of F, providing Result(1)as the thisvalue and providing the argument list passed into [[Construct]]as the argument values.
  7. If Type(Result(6))is Objectthen return Result(6).
  8. Return Result(1).

13.2.2[[Construct]]

调用对象的[[Construct]]属性时,将执行以下步骤:FunctionF

  1. 创建一个新的原生 ECMAScript 对象。
  2. 将 的[[Class]]属性设置Result(1)"Object"
  3. 获取 的原型属性的值F
  4. 如果Result(3)是对象,则将 的[[Prototype]]属性设置Result(1)Result(3)
  5. 如果Result(3)不是对象,则将 的[[Prototype]]属性设置Result(1)为原始Object原型对象,如15.2.3.1 中所述
  6. 调用 的[[Call]]属性F,提供Result(1)作为this值并提供[[Construct]]作为参数值传入的参数列表。
  7. 如果Type(Result(6))Object然后返回Result(6)
  8. 返回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在函数上使用关键字时,如果,

  1. function does not return anything, it will return an intended object
  1. 函数不返回任何东西,它将返回一个预期的对象

function User() {
  this.name = 'Virat'
}

var user = new User();
console.log(user.name); //=> 'Virat'

  1. function returns any truthycomplex object [object, array, function etc], that complex object takes priority and uservariable will hold the returned complex object
  1. 函数返回任何真实的复杂对象[对象、数组、函数等],该复杂对象优先,user变量将保存返回的复杂对象

function User() {
  this.name = 'Virat';
  return function(){};
}

var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function

  1. function returns any literal, constructor takes priority and it will return an intended object
  1. 函数返回任何文字,构造函数优先,它将返回一个预期的对象

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.

函数无法阻止创建对象,就像在调用函数之前那样。