返回

babel看class的继承:Object.setPrototypeOf(),__proto__

前端

babel看class(上) 中,我们探讨了 babel 如何将 class 语法转化为 JavaScript 代码。现在,让我们更深入地研究继承,看看 babel 如何处理它。

在 JavaScript 中,可以使用 Object.setPrototypeOf() 方法或 proto 属性来实现继承。

Object.setPrototypeOf()

Object.setPrototypeOf() 方法将一个对象的原型(proto)设置为另一个对象。如果存在 Object.setPrototypeOf(),babel 会使用它来实现继承。

class Parent {
  constructor(name) {
    this.name = name;
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }
}

const child = new Child('John', 30);

console.log(child.__proto__ === Parent.prototype); // true
console.log(Object.getPrototypeOf(child) === Parent.prototype); // true

在上面的示例中,babel 会将 Child 类的原型设置为 Parent 类的原型。因此,child 对象的 proto 属性和 Object.getPrototypeOf(child) 返回的值都指向 Parent 类的原型。

proto 属性

如果不存在 Object.setPrototypeOf(),babel 会直接使用 proto 属性来实现继承。

class Parent {
  constructor(name) {
    this.name = name;
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }
}

Child.prototype.__proto__ = Parent.prototype;

在上面的示例中,babel 会将 Child 类的原型(Child.prototype)的 proto 属性设置为 Parent 类的原型(Parent.prototype)。这将 Child 类的原型与 Parent 类的原型链接起来,实现继承。

重写prototype

当子类重写父类的 prototype 方法时,babel 会直接在子类的 prototype 上定义该方法。

class Parent {
  constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }

  getName() {
    return `${this.name} is ${this.age} years old.`;
  }
}

const child = new Child('John', 30);

console.log(child.getName()); // "John is 30 years old."

在上面的示例中,babel 会将 Child 类的 prototype 上的 getName() 方法直接定义为重写父类的方法。因此,当调用 child.getName() 时,会执行 Child 类的 getName() 方法,而不是 Parent 类的 getName() 方法。

总结

babel 通过使用 Object.setPrototypeOf() 方法或 proto 属性来实现 class 继承。当子类重写父类的 prototype 方法时,babel 会直接在子类的 prototype 上定义该方法。通过了解 babel 如何处理继承,我们可以更好地理解 JavaScript 中继承的机制。