[GAS][slack]営業日カウントダウンbotを作っている途中 その3 クラスで生成したインスタンス(オブジェクト)を変更、追加、削除するには


前回


今気になっていること

  1. クラスおさらい

  2. クラス化

  3. emoji-codeでもアイコンいけるんじゃないの?

  4. webhoook


3、4は、今とりあえず通知は出来てるからあと回しでもいいか…?

クラスのおさらい続き

インスタンスとして生成されたオブジェクトのメンバを変更、追加、削除


こんなコードがあって、こんな実行ログになる。

function cat() {
  class Cat {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }

    meow() {
      console.log(`Meow!`)
    }

    //5以上なら true
    isAdalt() {
      return this.age >= 5;
    }
  }

  const test1 = new Cat('チビ', 5);
  console.log(test1.name);
  test1.meow();
  console.log(test1.isAdalt());

  const test2 = new Cat('たま', 3);
  console.log(test2.name);
  test2.age += 5;
  // test2.meow();//通常パターン
  test2.meow('Meow!Meow!'); //NG
}


で、インスタンスとして生成後にたまの年齢の変更はできたわけ。
たまの鳴き声も変えてみたいんだけどどうしよう。

なお、前提としては、インスタンス生成後のメソッド変更はご法度なので、ここでやっているのは単なる興味です。

基本的に、インスタンスを生成後にメソッドを変更するのは、ご法度とされています。
もし変更したいなら、えばっさんのように別のメソッドを実装するといいと思います。

つじけ


クラス内のメソッドでデフォルト引数を指定してみる

元のクラス内のメソッドにデフォルト引数を設定して、こんなコードになる。

ここを

  meow() {
      console.log(`Meow!`)
    }


こう書き換える

    meow(nakigoeDefault= 'Meow') {
      console.log(nakigoeDefault)
    }


コード全体

function cat() {
  class Cat {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }

    meow() {
      console.log(`Meow!`)
    }

    meow(nakigoeDefault= 'Meow') {
      console.log(nakigoeDefault)
    }

    //5以上なら true
    isAdalt() {
      return this.age >= 5;
    }
  }

  const test1 = new Cat('チビ', 5);
  console.log(test1.name);
  test1.meow();
  console.log(test1.isAdalt());

  const test2 = new Cat('たま', 3);
  console.log(test2.name);
  test2.age += 5;
  // test2.meow();//通常パターン
  test2.meow('Meow!Meow!'); //OK


  console.log(test2.isAdalt());


}
test2.meow('Meow!Meow!')

ここで引数を指定して、たまの鳴き声を変更できた。

実行ログ


extends継承してoverrideオーバーライドしてみる

鳴き声の部分だけを元のクラスから継承して、そこだけ変更した場合。
えばたさんからご教示いただいたので、敬意をこめて function ebata で。

function ebata() {
  class Cat {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }

    meow() {
      console.log('Meow!');
    }

    //5以上なら true
    isAdalt() {
      return this.age >= 5;
    }
  }
  class Cat2 extends Cat {
    meow() {
      console.log('Meow!Meow!');
    }
  }

  const test1 = new Cat('チビ', 5);
  test1.meow();
  console.log(test1.isAdalt());

  const test2 = new Cat2('たま', 3);
  test2.meow();//通常パターン
  console.log(test2.isAdalt());

}

ほえ〜こういうのもあるのか。

ファイルの生成順に読み込まれる可能性があるとか(未検証)


GASのオーバライドこれとか

オーバーライドと、オーバーロード

ここがわかりやすかった。
https://wa3.i-3-i.info/diff455programming.html

オーバーライド→上書きしている、
オーバーロード→多重定義、積荷がいっぱい JavaScriptでは使えない?引数に工夫が必要?
https://hacknote.jp/archives/31788/

基本的に、インスタンスを生成後にメソッドを変更するのは、ご法度とされています。
もし変更したいなら、えばっさんのように別のメソッドを実装するといいと思います。
ただ、「メソッド名は同じにして、引数によってどのメソッドが走るか分岐したいんだけどな」、という需要もあると思います。
いまのところ、GASでは、引数を可変長引数(レスト構文)メソッド名(...args)にして、引数をメソッド内で判定するしかないと思います。
Javaには、引数によってどのメソッドを呼び出すか、というメソッドの多重定義(オーバーロード)が可能です。
JavaScriptでは多重定義ができませんで、一番最後に書かれているメソッドが呼び出されます。

つじけ

継承によるメソッドのオーバーライドと、オーバーロード、とても言葉が似てるので、覚えておいてください。
試験に出ます。(なんの)

つじけ

色々調べたらつじけさんの言ってることも理解できる(ような気がする


prototypeでやってみる

クラス名.prototype.メソッド名 = function() {} で書き換えできるとのこと。
GAS本184p

 taitoさんからご教示いただいたので、敬意をこめて function taito で

function taito() {
  class Cat {
    meow() {
      console.log('Meow!')
    }
  }
  const test2 = new Cat();
  test2.meow(); // -> Meow!
  Cat.prototype.meow = nakigoe => { console.log(nakigoe) };
  test2.meow('Meow!Meow!'); // -> Meow!Meow!
}

プロトタイプ。
そして
出たよアロー関数。いまだに苦手感ある。

プロトタイプ

インスタンスからクラスのプロパティを参照できる仕組み。

インスタンスとして生成されたものにそれぞれメソッドが作られちゃって、それ同じものなにもったいなくない?という発想なのはわかった。
その先がよくわからない。

写経してみる。

インスタンスとして生成されたpはメソッドを持っていない

うまいこと、インスタンスからはクラスのメソッドを参照している。


function myFunction06_03_02() {

  class Person {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }

    greet() {
      console.log(`Hello!I'm${this.name}!`)
    }

    isAdalt() {
      return this.age >= 18;
    }
  }

  const p = new Person('Bob', 25);

  p.greet = function () {
    console.log(`Good bye! I'm ${this.name}!`);
  };
  p.greet();

  console.log(Person.prototype.greet.toString());
  console.log(p.greet.toString());
}

実行結果
Good bye! I'm Bob!
greet() { console.log(`Hello!I'm${this.name}!`) }
function () { console.log(`Good bye! I'm${this.name}!`); }

メソッドの書き換え。

ふむふむ、やってることはわかってきたぞ。
で、これをアロー関数で書くには...?それがわかれば
Cat.prototype.meow = nakigoe => { console.log(nakigoe) };
もわかりそうな気がする。


あ〜ちょっとわかんなくなってきた。
クラス化するにあたって色々理解したいけど横道に逸れてきた気もする。


ううううう、今日はここまで。
頭悪くて嫌になるな。

#ノンプロ研
#クラス
#継承
#オーバーロード
#オーバーライド
#プロトタイプ
#GAS

いいなと思ったら応援しよう!

good-sun(a03)
いただいたサポートで、書籍代や勉強費用にしたり、美味しいもの食べたりします!