【问题标题】:Can ES6 class inheritance be translated into equivalent ES5 code?ES6 类继承可以翻译成等效的 ES5 代码吗?
【发布时间】:2020-01-11 05:39:17
【问题描述】:

This answer 展示了一个简单的 ES6 类:

class A {
  constructor() {
    this.foo = 42;
  }

  bar() {
    console.log(this.foo);
  }
}

相当于下面的 ES5 代码:

function A() {
  this.foo = 42;
}

A.prototype.bar = function() {
  console.log(this.foo);
}

同样可以将 ES6 类继承转换为 ES5 代码吗?什么是 ES5 等价于以下派生类?

class B extends A {
  constructor() {
    super();
    this.foo2 = 12;
  }

  bar() {
    console.log(this.foo + this.foo2);
  }

  baz() {
    console.log(this.foo - this.foo2);
  }
}

【问题讨论】:

  • 查看babeljs.io并在babeljs.io/repl
  • 以及您询问的代码...babeljs.io/…
  • 这是一个关于prototypal inheritance from MDN的好指南
  • 是的。类符号只是语法糖。实际上,您可以使用 ES5 代码做更多事情。例如,类表示法不支持类的静态数据,并且使用 ES5 语法,您可以使用命名函数(因此函数可以调用自身)。如果需要,您可以将两者混合使用。

标签: javascript class inheritance ecmascript-6 prototype


【解决方案1】:

就其之前的实现方式而言(忽略属性可枚举性和从 ES5 兼容代码扩展实际 ES6 类等确切行为)的等价物是:

  • 将子原型设置为继承父原型的新对象
  • 从子构造函数调用父构造函数
function B() {
  A.call(this);
  this.foo2 = 12;
}

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

B.prototype.bar = function () {
  console.log(this.foo + this.foo2);
};

B.prototype.baz = function () {
  console.log(this.foo - this.foo2);
};

还可以使用修改现有原型的实际工具继承构造函数的属性(“静态”):B.__proto__ = A

【讨论】:

  • 最好使用Object.defineProperty 将构造函数属性设置为不可枚举,以防止它在for in... 循环中被迭代,但如果不是问题,那么应该没问题.
  • @ryeballar 如果有多个属性,Object.defineProperties 也可用。
  • 谢谢。看起来 Babel 生成的代码或多或少与此等效,包括 Object.setPrototypeOf(B, A) 步骤。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 2015-02-21
  • 2016-11-20
  • 2017-02-28
相关资源
最近更新 更多