published on

构造函数中的 return

class Parent {
  constructor() {
    this.name = 'tom';
    return { aa: 1 };
  }
}

class Child extends Parent {
  constructor() {
    super();
    this.name = 'sd';
  }
}

const child = new Child();

console.log(child);

看下编译出的代码

var Parent = function Parent() {
  _classCallCheck(this, Parent);

  this.name = 'tom';
  return { aa: 1 };
};

var Child = (function(_Parent) {
  _inherits(Child, _Parent);

  function Child() {
    _classCallCheck(this, Child);

    var _this = _possibleConstructorReturn(
      this,
      (Child.__proto__ || Object.getPrototypeOf(Child)).call(this),
    );

    _this.name = 'jack';
    return _this;
  }

  return Child;
})(Parent);

var child = new Child();

奇怪的是 aa 为什么会跑到 child 上去

关键是 _possibleConstructorReturn 函数

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError(
      "this hasn't been initialised - super() hasn't been called",
    );
  }
  return call && (typeof call === 'object' || typeof call === 'function')
    ? call
    : self;
}

Child inherits Parent 继承父类,_possibleConstructorReturn()传入的是参数是 child 的 this,和 Parent.call(this), parent.call(this) 返回的是{ aa: 1 } .所以相当于_possibleConstructorReturn(this, { aa: 1 }),根据这个函数里的内容,这里应该返回第二个参数 call,也就是 { aa: 1 },所以 _this 就是 { aa: 1}
所以得到的结论是如果constructor里调用super(),并且父类的构造函数有返回值,返回值是一个对象的话或者 function,那么子类中的 this 就先被赋予这个值