构造函数可以返回哪些值以避免返回此值?

时间:2009-12-30 02:08:29

标签: javascript constructor new-operator

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

示例:

function Foo () {
  return something;
}

var foo = new Foo ();

如果我没弄错,如果something是非函数原语,则会返回this。否则返回something。这是对的吗?

IOW,something可以(new Foo () instanceof Foo) === false采用什么值?

6 个答案:

答案 0 :(得分:155)

[[Construct]]内部属性描述了确切的条件,new运算符使用了该属性:

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

  

13.2.2 [[Construct]]

     

[[Construct]]对象Function的{​​{1}}属性为   被叫,采取以下步骤:

     
      
  1. 创建一个新的本机ECMAScript对象。
  2.   
  3. F的{​​{3}}属性设置为Result(1)
  4.   
  5. 获取"Object"
  6. 的prototype属性的值   
  7. 如果F是对象,请将Result(3)的{​​{3}}属性设置为Result(1)
  8.   
  9. 如果Result(3)不是对象,请将Result(3)的{​​{3}}属性设置为原始Result(1)原型对象为   在[[Class]]中描述。
  10.   
  11. 调用Object的{​​{3}}属性,提供F作为Result(1)值,   提供传递给this的参数列表作为   参数值。
  12.   
  13. 如果[[Construct]]是   [[Prototype]](Result(6))然后返回Object
  14.   
  15. 返回Result(6)
  16.         

    查看步骤7和8,只有在返回时才会返回新对象   类型Result(1)(从Result(6)构造函数返回的值   function)一个对象。

答案 1 :(得分:4)

具体例子 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('%')));

答案 2 :(得分:2)

我找不到有关此事的任何文件,但我认为你是对的。例如,您可以从构造函数返回new Number(5),但不能返回文字5(将被忽略并返回this)。

答案 3 :(得分:1)

试图用简单的话来说明几点。

在javascript中,当您在函数上使用new关键字时,如果

  1. 函数不返回任何内容,它将返回预期的对象

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

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

  1. 函数返回任何真实复杂对象[对象,数组,函数等],该复杂对象具有优先级,并且user变量将保存返回的复杂对象

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

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

  1. 函数返回所有文字,构造函数具有优先权,并将返回预期的对象

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

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

答案 4 :(得分:0)

作为旁注,返回值或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()是内部使用的,可以被利用以获得乐趣和利润。您甚至可以创建副作用,例如:

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添加到任何对象,它可以表现为数字:

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

您可以利用它来创建一个总是返回新GUID的对象。

答案 5 :(得分:-1)

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

该函数无法阻止创建对象,因为这是在调用函数之前完成的。