js中的 constructor 除了纠正指向到构造函数本身, 有啥更加实际的意义和编码需要的场景吗?

constructor 是否仅仅作为一个原型对象的构造器指示标志, 并不受使用的影响?

function User() {

}

User.prototype = {

}

const user = new User();
console.log(user instanceof User); // true,  并不影响


user.constructor === User; // false, 除了这个判断还有啥使用场景吗?

那就自问自答一波,没有合适答案

为什么希望在覆盖 prototype 的时候希望纠正 constructor 属性?

  1. 可以在构造函数内部通过 this.constructor 二次实例化, 避免在构造函数被覆盖的时候报错.
  2. 构造函数可以通过外部实例化, 再次 new
  3. 作为一个良好的习惯, 方便查阅继承关系(实际的原型链继承关系并不受影响, 只是对应的 constructor 函数 不一致)

针对第 1 条,请看这个例子

    function User(loop) {
        if (loop) {
            return new User();
        }
    }

    const BaseUser = User;
    User = null;

    // 此时在构造函数中执行会报错,因为User 已经被覆盖
    const baseUser = new BaseUser();


    // 纠正, 始终用this.constructor 就更加安全
    function User(loop) {
        if (loop) {
            return new this.constructor();
        }
    }

总结:
有时候在构造函数内部还会调用构造函数,这种情况不要使用构造函数的名字,而应该使用 this.constructor() 来调用

针对第 2 条

  function User() {

  }

  User.prototype = {
    constructor: User,
    getInfo: function() {
       return {};
    }
  };

  const user = new User();
  // 如果不纠正这里会出现实例化报错,或者实例化不是所期望的对象
  const user2 = new user.constructor()
针对早期浏览器访问
    // 针对早期浏览器访问
    function User() {

    }

    const user = new User();
    user.constructor.prototype // 拿到原型属性
阅读 1.2k
1 个回答

为什么希望在覆盖 prototype 的时候希望纠正 constructor 属性?

  1. 可以在构造函数内部通过 this.constructor 二次实例化, 避免在构造函数被覆盖的时候报错.
  2. 构造函数可以通过外部实例化, 再次 new
  3. 作为一个良好的习惯, 方便查阅继承关系(实际的原型链继承关系并不受影响, 只是对应的 constructor 函数 不一致)

针对第 1 条,请看这个例子

    function User(loop) {
        if (loop) {
            return new User();
        }
    }

    const BaseUser = User;
    User = null;

    // 此时在构造函数中执行会报错,因为User 已经被覆盖
    const baseUser = new BaseUser();


    // 纠正, 始终用this.constructor 就更加安全
    function User(loop) {
        if (loop) {
            return new this.constructor();
        }
    }

总结:
有时候在构造函数内部还会调用构造函数,这种情况不要使用构造函数的名字,而应该使用 this.constructor() 来调用

针对第 2 条

  function User() {

  }

  User.prototype = {
    constructor: User,
    getInfo: function() {
       return {};
    }
  };

  const user = new User();
  // 如果不纠正这里会出现实例化报错,或者实例化不是所期望的对象
  const user2 = new user.constructor()
针对早期浏览器访问
    // 针对早期浏览器访问
    function User() {

    }

    const user = new User();
    user.constructor.prototype // 拿到原型属性
推荐问题
宣传栏