JavaScript 构造函数的返回值

当使用 new 操作符调用构造函数时,构造函数的内部属性 [[Construct]] 属性将被调用。这个属性定义在 ECMA-262 3rd Edition 的 [[Construct]]部分。

构造函数 F 的内部属性 [[Construct]] 被调用时,以下步骤将会执行:

  1. 创建 一个原生的 ECMAScript 对象,记为 o
  2. 设定 o 的 [[Class]] 属性为 “Object”,即 o.Class = “Object”;
  3. 获取 F 的 prototype 属性的值,记为 Fp ;
  4. 若 Fp 是一个对象,设定 o 的 [[Prototype]] 属性为 Fp,即 o.Prototype = Fp;
  5. 若 Fp 不是一个对象,设定 o 的 [[Prototype]] 属性为 Object prototype 的值。
  6. 调用 F 的 [[Call]] 属性。将 o 作为 this 的值,传入 [[Construct]] 的参数作为参数,即 F.call(o, arguments),执行结果 记为 Fc
  7. 若 Fc 是一个对象, 那么返回 Fc;
  8. 返回 o

从第 7 步可以看到,当构造函数F执行后的返回值是一个对象时,new F() 的值即为返回的对象:

1
2
3
4
5
6
7
8
9
10
11
12
function ConstructorReturnObject(){
this.test = "test";
return new String("testString");
}
var t2 = new ConstructorReturnObject();
// t2 并没有 test 属性
console.log(t2.test); // undefined
// t2的类型是 String
// 输出 [object String]
console.log(Object.prototype.toString.call(t2));

当构造函数 F 执行的返回值类型非对象时,new F() 即返回 this

1
2
3
4
5
6
7
8
function ConstructorReturnNonObjectValue() {
this.test = "test";
return "testString";
}
var t1 = new ConstructorReturnNonObjectValue();
// 输出 {test: "test"}
console.log(t1);

参考资料:

0%