【问题标题】:How is class extends handled in non-ES6 Javascript?非 ES6 Javascript 中如何处理类扩展?
【发布时间】:2018-01-04 17:00:28
【问题描述】:
对于 Javascript 的基于原型的继承系统,ES6 class 关键字只是 syntactic sugar 是 said。这一点很明显,只有一个例外:extends 关键字。例如:
class Foo {
constructor(){
this.sayHello = () => console.log('Hello')
}
}
class Bar extends Foo {
constructor(){
super();
this.sayGoodbye = () => console.log('Goodbye');
}
}
如果class 只是语法糖,那么这里到底发生了什么?是否有一个标准的
【问题讨论】:
标签:
javascript
ecmascript-6
【解决方案1】:
是否有标准的
JavaScript 有一个原型继承模型,这也是您使用class 关键字获得的。您的代码大致相当于:
function Foo () {
this.sayHello = () => console.log('Hello')
}
function Bar () {
// super();
Foo.call( this );
this.sayGoodbye = () => console.log('Goodbye');
}
// extends
Bar.prototype = Object.create( Foo.prototype );
Bar.prototype.constructor = Bar;
【解决方案2】:
这里到底发生了什么?
这是 JS 引擎的一个实现细节。
是否有一个标准的
“标准”可能太过分了,但 Babel 是一个众所周知的转译器,可以将 ES6 转换为 ES5。
它给出了这个:
'use strict';
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; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Foo = function Foo() {
_classCallCheck(this, Foo);
this.sayHello = function () {
return console.log('Hello');
};
};
var Bar = function (_Foo) {
_inherits(Bar, _Foo);
function Bar() {
_classCallCheck(this, Bar);
var _this = _possibleConstructorReturn(this, (Bar.__proto__ || Object.getPrototypeOf(Bar)).call(this));
_this.sayGoodbye = function () {
return console.log('Goodbye');
};
return _this;
}
return Bar;
}(Foo);