Skip to content

Instantly share code, notes, and snippets.

@ommadawn46
Last active December 8, 2020 01:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ommadawn46/a351fb6d07d7fb07cb362ddcdcefa561 to your computer and use it in GitHub Desktop.
Save ommadawn46/a351fb6d07d7fb07cb362ddcdcefa561 to your computer and use it in GitHub Desktop.
Javascriptのclass構文について調べたこと

Javascriptのclass構文について

class構文

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes

  • ECMAScript 6で追加された
  • 昔はprototypeを利用してクラス的な振る舞いをするオブジェクトを作成することが多かったが、class構文を使えば簡単にクラスを扱うことができる
    class Polygon {
      constructor(height, width) {
        this.height = height;
        this.width = width;
      }
    
      get area() {
        return this.calcArea();
      }
    
      calcArea() {
        return this.height * this.width;
      }
    }
    
    const square = new Polygon(10, 10);
    
    console.log(square.area);
    // 100

再定義はできない

  • 同じclass名で重複して定義するとエラーとなる
    class Animal{
      constructor(){
        this.name = 'animal'
      }
    };
    
    class Animal{};
    // VM338:1 Uncaught SyntaxError: Identifier 'Animal' has already been declared
    //     at <anonymous>:1:1

new演算子を使わず直接呼び出すことが禁止されている

  • NG

    Animal()
    // VM344:1 Uncaught TypeError: Class constructor Animal cannot be invoked without 'new'
    //     at <anonymous>:1:1
  • OK

    new Animal()
    // Animal {name: "animal"}

スタティックメソッドはprototypeに追加されない

  • インスタンスから直接呼び出すことは出来ない
  • クラスから呼び出して使用する
    class Animal{
      constructor(){
        this.name = 'animal'
      }
      static run(){
        console.log('running!');
      }
      sound(){
        console.log('blah');
      }
    }
    
    const some_animal = new Animal();
    some_animal.run()
    // VM405:1 Uncaught TypeError: some_animal.run is not a function
    //     at <anonymous>:1:13
    
    Animal.prototype.run()
    // VM413:1 Uncaught TypeError: Animal.prototype.run is not a function
    //     at <anonymous>:1:1
    
    Animal.run()
    // running!

extendsを使って継承できる

  • Javaっぽい書き方
    class Dog extends Animal {
      constructor(name){
        this.name = name
      }
      sound(){
        console.log('wan');
      }
    };
    let pochi = new Dog('pochi');
    
    pochi.sound();
    // wan
    
    Dog.run()
    // running

プロトタイプチェーンの(ほぼ)シンタックスシュガーである

  • 内部的には昔ながらのプロトタイプチェーンによって実現されている

    typeof(Dog)
    // "function"
    
    typeof(pochi)
    // "object"
    pochi.constructor === Dog
    // true
    
    pochi.constructor.__proto__ === Animal
    // true
    
    pochi.constructor.__proto__.__proto__ === Function.prototype
    // true
    
    pochi.constructor.__proto__.__proto__.__proto__ === Object.prototype
    // true
    pochi.__proto__ === Dog.prototype
    // true
    
    pochi.__proto__.__proto__ === Animal.prototype
    // true
    
    pochi.__proto__.__proto__.__proto__ === Object.prototype
    // true
    • ただし、classはnew演算子無しで呼び出すとエラーになるなどの点でコンストラクタ関数とは異なっている
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment