前回に続いて、プロトタイプチェーン(継承)を勉強というか調べてみました
ECMAScript6ではclass構文が使えるので以下のように書けますが
es6.js
class Dog{
constructor(name){
this.name=name;
console.log('dog');
}
say(){
console.log(this.name);
}
}
class MyDog extends Dog{
constructor(name){
super();
console.log('mydog');
}
say(){
console.log('my'+this.name);
}
}
これをbabelでECMAScript5にすると以下のようになりました。
babelの出力そのままではなく、コメントを加えてインデントを調整しています。
関数の巻き上げがあるせいでいまいち読み解けないです。
es5.js
'use strict';
// クラスに相当するfunctionの作成
var _createClass = function () {
// functionへのproperty設定
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor)
descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
// 普通のプロパティはprototypeに、static(newしなくても使える)ならfunctionに設定する
return function (Constructor, protoProps, staticProps) {
if (protoProps)
defineProperties(Constructor.prototype, protoProps);
if (staticProps)
defineProperties(Constructor, staticProps);
return Constructor;
};
}();
// 何のためにあるかよく分かっていない
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;
}
// newで呼ばれているかチェックしている?
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Dog = function () {
function Dog(name) {
_classCallCheck(this, Dog);
this.name = name;
console.log('dog');
}
_createClass(Dog, [{
key: 'say',
value: function say() {
console.log(this.name);
}
}]);
return Dog;
}();
var MyDog = function (_Dog) {
_inherits(MyDog, _Dog);
function MyDog(name) {
_classCallCheck(this, MyDog);
var _this = _possibleConstructorReturn(this, (MyDog.__proto__ || Object.getPrototypeOf(MyDog)).call(this));
console.log('mydog');
return _this;
}
_createClass(MyDog, [{
key: 'say',
value: function say() {
console.log('my' + this.name);
}
}]);
return MyDog;
}(Dog);
なかなか分からないものを使いにくいし、基本的には前回で事足りるような気がします。
TypeScriptはまた少し違っているみたいですね。。。