██████████ のブログ

なんか技術的なメモ & ブクマ (no affiliate ads)

JavaScript の継承らへん

ゴチャゴチャしてきたので自分のために JavaScript の継承らへんを整理した

 

ChildClass のインスタンスを生成する

  1. let c = new ChildClass();
  2. {} が生成される
  3. "{} は ChildClass.prototype を継承する"
    {}.__proto__ = ChildClass.prototype; ?
  4. コンストラクタ関数 ChildClass() が呼ばれる ∧
    ChildClass() において this が {} に紐付けられる ∧
    ChildClass() によって {} のプロパティが初期化される
  5. 変数 c が {} に紐付けられる

(JavaScript: The Good Parts (2008) の new を葬り去るという目論見は失敗した模様)

new - JavaScript | MDN

Object.prototype.constructor - JavaScript | MDN

 

ParentClass のサブクラスとして ChildClass をサブクラス化する ("ChildClass は ParentClass から継承する")

class ChildClass extends ParentClass { ... }
let c = new ChildClass();
c instanceof ChildClass === c instanceof ParentClass; //=> true
c.__proto__ === ChildClass.prototype; //=> true
c.__proto__ === ParentClass.prototype; //=> false
ChildClass.__proto__ === ParentClass.prototype; //=> false
ChildClass.__proto__ === ParentClass; //=> true
ParentClass.__proto__ === Function.prototype; //=> true

MDN にそれらしい記述は見当たらないけど ↑ の実験によるとプロトタイプチェーンは c ---> ChildClass.prototype ---> ParentClass ---> Funciton.prototype ---> ... となって extends で生じたサブクラスとスーパークラスの関係だけちょっと特殊な感じ

extends - JavaScript | MDN

 

extends 構文中の super がやっていること

function ChildClass() {
    ParentClass.call(this);
}

Object.create() - JavaScript | MDN

 

Object.create() 

let c = Object.create(ChildClass [, propertiesObject ])
  • c ---> ChildClass という順でプロトタイプチェーンが辿られる
  • c は (c.prototype にではなく) c 直下にプロパティ p_i たちをもつ (c は自身のプロパティとして p_i たちをもつ) (つまり p_i たちはプロトタイプチェーンから辿られることはない)
    propertiesObject は {p_0: プロパティ記述子, p_1: プロパティ記述子, ...} というオブジェクト
  • new は operand のインスタンスを生成する (コンストラクタ関数が呼ばれる),Object.create() は第一引数を継承するオブジェクトを生成する (コンストラクタ関数は呼ばれない)

Object.create() - JavaScript | MDN

プロパティ記述子の各項目の意味
Object.defineProperties() - JavaScript | MDN

 

extends がやっていること

Object.create() を用いた古典的な継承 - Object.create() - JavaScript | MDN

B は A から継承します - 継承とプロトタイプチェーン - JavaScript | MDN