构造函数中return

780 阅读2分钟

构造函数中一般情况下是不应该return的。如果 return 了,分为 return 值类型return 引用类型

先来看下基本代码

function Person(name) {
  this.name = name;
  // return 1; // 情况1:return 值类型
  // return { name: 'Error' }; // 情况2:return 引用类型
}
const p = new Person('xm')

分别打印一下这个 p 得到了两种情况:

  1. returnreturn 值类型 是第一种情况。

    结果就是输出 Person { name: 'xm' },这是正常的。

  2. return 引用类型就是第二种情况了

    输出了 { name: 'Error' },也就是我们return的引用类型,此时,我们若创建原型方法也不会挂到实例上,调用时会报错TypeError

原型和返回的值都不是我们期望的结果,这自然是归功于于 new 的功劳

那我们模拟一个 new ,看一下 new 一个构造函数时发生了什么

function New(Func, ...rest) {
  // 1. 创建一个空对象
  const obj = {};
  // 2. 将空对象的指针指向构造函数的原型
  obj.__proto__ = Func.prototype;
  // 3. 将执行上下文this绑定到上面创建的新对象上
  const result = Func.apply(obj, rest);
  // 4. 如果构造函数返回「引用类型」的值,那么将其返回。否则返回上面创建的对象
  return result instanceof Object ? result : obj;
}

答案很明显,就是 new 的时候会判断构造函数的返回值类型所致

使用一下我们模拟实现的 New,来试下错误

function Person(name) {
  this.name = name;
  return { name: 'Error' }; // return 引用类型
}
const p = New(Person, 'xm')
console.log(p);

Person.prototype.sayName = function() {
  console.log('我的名字: ', this.name);
}
p.sayName(); 
  • 报错:TypeError: p.sayName is not a function

另外要注意下:原型方法尽量不要使用箭头函数: 箭头函数不绑定this, 无法获取实例对象上的属性和方法

结论

JavaScript构造函数中:

  • 如果 return 值类型,那么对构造函数没有影响,实例化对象正常返回;
  • 如果 return 引用类型(数组、函数、对象),那么实例化对象就会返回该引用类型