什么是从构造函数返回?

如果我在构造函数中返回一些值或对象,var会得到什么?

function MyConstroctor() { //what in case when return 5; //what in case when return someObject; } var n = new MyConstroctor(); 

在两种情况下都会得到什么?

其实它是一个测验问题,会是什么答案?
从自定义对象构造函数返回什么?
a)新实例化的对象
b)未定义 – 构造函数不返回值
c)不pipe是什么回报声明
d)不pipe回报是什么, 新实例化的对象如果没有返回语句

我发现这个伟大的链接:

JavaScript:构造函数返回值

上面的第二部分的魔力是构造函数返回一个特定的,可能是先存的对象的能力,而不是对新实例的引用。 这将允许您自己pipe理实际实例的数量,如果需要的话; 可能是由于资源有限或者是什么原因。

 var g_deebee = new Deebee(); function Deebee() { return g_deebee; } var db1 = new Deebee(); var db2 = new Deebee(); if (db1 != db2) throw Error("JS constructor returned wrong object!"); 

简答

构造函数返回this对象。

 function Car(){ this.num_wheels = 4; } // car = {num_wheels:4}; var car = new Car(); 

长答案

通过Javascript规范,当一个函数被new调用时,Javascript会创build一个新的对象,然后将该对象的“constructor”属性设置为被调用的函数,最后将该对象赋值给这个名字。 然后您可以访问this对象的函数体。

一旦函数体被执行,Javascript将返回:

任何对象,如果函数手动返回一个:

 function Car(){ this.num_wheels = 4; return {num_wheels:37}; } var car = new Car(); alert(car.num_wheels); // 37! 

如果函数没有return语句,或者函数返回的是非objecttypes的值,则返回该object

 function Car() { this.num_wheels = 4; return 'VROOM'; } var car = new Car(); alert(car.num_wheels) // 4 alert(Car()); // No 'new', so this alerts 'VROOM' 

基本上,如果你的构造函数返回一个原始的值 ,比如一个string,数字,布尔值,空值或者未定义的值(或者你不返回任何相当于返回undefined ),那么从构造函数的prototypeinheritance的新创build的对象将会回。

当用new关键字调用时,这是您在构造函数中使用this关键字访问的对象。

例如:

 function Test() { return 5; // returning a primitive } var obj = new Test(); obj == 5; // false obj instanceof Test; // true, it inherits from Test.prototype Test.prototype.isPrototypeOf(obj); // true 

但是,如果返回的值是一个对象引用,那将是返回的值,例如:

 function Test2() { this.foo = ""; // the object referred by `this` will be lost... return {foo: 'bar'}; } var obj = new Test2(); obj.foo; // "bar" 

如果您对new操作符的内部感兴趣,可以检查[[Construct]]内部操作的algorithm,是负责创build从构造函数的原型inheritance的新对象,并决定返回的内容:

13.2.2 [[Construct]]

Function对象F[[Construct]]内部方法被调用时,可能会有一个空的参数列表,则执行以下步骤:

  1. obj是新创build的本地ECMAScript对象。
  2. 按照8.12的规定设置obj所有内部方法。
  3. obj[[Class]]内部属性设置为"Object"
  4. obj[[Extensible]]内部属性设置为true
  5. 让proto成为用参数"prototype"调用F[[Get]]内部属性的值。
  6. 如果Type(proto)是Object , set the obj , set the [[Prototype]]内部属性设置为proto。
  7. 如果Type(proto)不是Object,则将obj的[[Prototype]]内部属性设置为标准内置Object对象原型对象,如15.2.4所述。
  8. 设结果为调用F的[[Call] ]内部属性的结果,提供obj作为该值,并将传递给[[Construct]]的参数列表提供为args。
  9. 如果Type(result)是Object,则返回结果。
  10. 返回obj

你不应该在构造函数中返回任何东西。 构造函数用于初始化对象。 如果你想知道发生了什么,如果你返回5那么n将只是一个空对象,如果你返回例如{ a: 5 } ,那么n将有一个属性a=5

要回答你的具体问题:

 function MyConstructor() { return 5; } var n = new MyConstructor(); 

n是MyConstructor的一个对象实例。

 function SomeObject(name) { this.name = name; this.shout = function() { alert("Hello " + this.name) } } function MyConstructor() { return new SomeObject("coure06"); } var n = new MyConstructor(); n.shout(); 

n是SomeObject的一个实例(调用n.shout()来certificate它)

为了使这一切都清楚…

1)如果你返回一个原始types,如数字或string,它将被忽略。 2)否则,你会传回对象

函数和构造函数在JavaScript中完全相同,但是如何调用它们会改变它们的行为。 下面是一个简单的例子

 function AddTwoNumbers(first, second) { return first + second; } var functionCall = AddTwoNumbers(5, 3); alert(functionCall);// 8 var constructorCall = new AddTwoNumbers(5, 3); alert(constructorCall);// object 

你不能从构造函数中返回任何东西!

当使用new关键字创build类的新实例(新对象)时,将调用该类的构造函数。 构造函数用于初始化对象的实例variables(字段)。 构造函数与方法类似,但有一些重要的区别。

  • 构造函数名称是类名称。 构造函数必须与其所在的类具有相同的名称。
  • 默认的构造函数。 如果您没有为类定义构造函数,编译器会自动创build一个默认的无参数构造函数。 默认构造函数调用默认的父构造函数(super()),并将所有实例variables初始化为默认值(数字types为零,对象引用为null,布尔值为false)。
  • 默认的构造函数只有在没有构造函数的情况下才被创build。 如果您为您的类定义了任何构造函数,则不会自动创build默认构造函数。
  • 方法和构造函数的区别
    • 在构造函数签名(头文件)中没有返回types。 该值本身就是这个对象,所以不需要指示返回值。
    • 在构造函数的主体中没有return语句。
    • 构造函数的第一行必须是对同一个类中的另一个构造函数(使用this)的调用,或者是对超类构造函数(使用super)的调用。 如果第一行不是这些,编译器会自动向无参数的超类构造函数插入一个调用。

在查看源代码时,构造函数和方法之间的语法差异有时很难看出来。 如果有一个关键字可以像某些语言那样清楚地标记构造函数,那就更好了。

  • this(…) – 在同一个类中调用另一个构造函数。 通常,只有less数参数的构造函数会调用具有更多参数的构造函数,为缺less的参数提供默认值。 使用它来调用同一个类中的其他构造函数。
  • 超(…)。 使用super来调用父类中的构造函数。 调用超类的构造函数必须是构造函数体中的第一个语句。 如果您对超类中的默认构造函数满意,则不需要调用它,因为它会自动提供。

显式的这个构造函数调用的例子

 public class Point { int m_x; int m_y; //============ Constructor public Point(int x, int y) { m_x = x; m_y = y; } //============ Parameterless default constructor public Point() { this(0, 0); // Calls other constructor. } . . . } 

super(…) – 超类(父)的构造函数

一个对象具有它自己的类的字段加上它的父类,祖父类的所有字段,一直到根类Object。 有必要初始化所有的字段,因此所有的构造函数都必须被调用! Java编译器自动在构造函数链接过程中插入必要的构造函数调用,或者您可以显式执行。

如果没有构造函数调用作为构造函数的第一个语句,Java编译器会向父构造函数(超级)插入一个调用。 以下是上面的构造函数的等价物。

 // Constructor (same as in above example) public Point(int x, int y) { super(); // Automatically done if you don't call constructor here. m_x = x; m_y = y; }