この記事はノンプロ研の第4期中級GAS講座のための事前課題をするなかで、新しく知ったこと、わからなかったこと、気づいたこと、調べたことなどを発表する記事です。
仕事の事情もあり、年末に入会したノンプロ研。入会間もないですがすごく居心地が良く(社会情勢により完全オンライン移行中なのにちょっと不思議な表現ですが)、とても良い学びの場になると感じています。
会の重要なモットーでもある”教えることは2度学ぶこと”を実行するためにも、事前課題から自分の学びはアウトプットしていこうかと思いました。
この記事では、オブジェクトに関してあった発見を書こうと思います。具体的には、GASでのthisの振る舞いについてです。
クラス定義時のthis
事前課題前のわたしのthisの理解は、インスタンスメソッドの定義でインスタンスそれ自身を指す使い方のみでした。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
isAdult() {
return this.age >= 18;
}
}
const alice = new Person('Alice', 13);
alice.greet(); // "Hello! My name is Alice."
オブジェクト定義時のthis
インスタンスでない通常の(?)オブジェクトにもメソッドを持たせることができます(事前課題で初めて知った)。
const person = {
name: 'John Doe',
age: 42,
isAdult() {
return this.age >= 18;
}
};
console.log(person.isAdult()); // true
メソッド追加時のthis
このpersonにgender属性とisMale()メソッドを持たせるとします。isMale()は自身のgenderがmaleであるかどうかを返すメソッドです。person.isMaleにfunctionキーワードで代入することで実現できます。
const person = {
name: 'John Doe',
age: 42,
isAdult() {
return this.age >= 18;
}
};
person.gender = 'male';
person.isMale = function() {
return this.gender === 'male';
}
console.log(person.isMale()); // true
ところで、personの定義部分ではES6で導入された省略記法を使っています(これも初見)。
const person = {
...
isAdult() { ... }
}
後からメソッドを追加する時にも、ES6っぽい書き方ができないかな?と思いました。
ES6以降導入された、アロー関数を使って定義してみます。
const person = { ... };
person.isMale = () => {
return this.gender === 'male';
}
わーい今っぽい。
ところが、実際にこれでperson.isMale()をしてみるとfalseになってしまいました。
const person = { ... };
person.gender = 'male';
person.isMale = () => {
return this.gender === 'male';
}
console.log(person.isAdult()); // false
this.genderがmaleになっていないということなのかな?と思ってthis.genderを調べてみると、this.genderがundefinedになっていました。
そこでthis自体もconsole.log()してみると、thisがグローバルオブジェクトになっていることがわかりました。
※answer...というのは、事前課題の解答として自分が同一プロジェクト内に書いている関数たちです。
オブジェクト定義のその中で書かないと、thisはそのオブジェクトを指してくれないんですね。
まとめ
ということで、メソッド定義の際のthisの扱いには注意が必要、ということを改めて発見できました。
書きながら調べてみたら、タカハシさんがすでに思いっきりこのテーマを扱っていたのでたはは〜という感じでしたが、自分で書いてみることで勉強になったと思います。演習もやったという気持ちになるし、また書きたいと思っています。読んでくださった方の参考になれば幸いです。
