LoginSignup
1
0

More than 5 years have passed since last update.

JavaScriptのプロトタイプチェーン(継承)について ES6のclass

Last updated at Posted at 2018-02-20

前回に続いて、プロトタイプチェーン(継承)を勉強というか調べてみました

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はまた少し違っているみたいですね。。。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0