みなさんこんにちは!GASおじさんです。
「GASでスプレッドシートを自由自在に操るためのスキル習得講座」の第11回です。
前回の記事はこちら。
前回はTextFinderを使って行と列を特定する方法について解説しました。
今回は一旦練習問題から離れて、これまで何気なく使っていた「オブジェクト」や「メソッド」について学び、より効率の良いプログラムを書くための知識を身につけていただきます。
オブジェクトについて学ぼう
さて、これまで何気なく使っていた「オブジェクト」という言葉ですが、以下のような場面でたびたび出てきていました。
sheetオブジェクトに対して
【GASの始め方】応用問題で関数について学ぼう(第5回の記事)より引用getLastRow()
メソッドを使うと、そのシートの最終行を取得することができる。
まずはすべてのシートオブジェクトを取得する
getSheets()
メソッドについて紹介します。スプレッドシートオブジェクト
【GASの始め方】for文とif文でデータ抽出して配列を生成しよう(第9回の記事)より引用ss
に対してgetSheets()
メソッドを使うと、すべてのシートオブジェクトを配列形式で取得することができます。
このようにcreateTextFinderメソッドを使うことで、TextFinderオブジェクトを生成し、それに対して
【GASの始め方】TextFinderで行と列を特定しよう(第10回の記事)より引用findNext().getRow()
とするとそのセルの行数を取得することができるのです。
これまで何の説明もなく使っていたこの「オブジェクト」という言葉。
英語のobjectを直訳すると、「物体」とか「対象」という意味になりますが、そもそもこのオブジェクトとは一体何なのでしょうか?
解説していきます。
まずは配列と比較しながら学ぶ
オブジェクトは別名「連想配列」と呼ばれることもありますが、その名の通り「配列」と良く似た概念ですので、最初は配列と比較しながら学ぶとわかりやすいです。
まず配列はどんなものだったかというと、以下のように複数のデータを管理するときに用いる書き方でした。
const students = ['sato', 'suzuki', 'takahashi'];
console.log(students[0]);
配列の特徴としては、
- ブラケット
[ ]
で定義する [ ]
の中の個別のデータのことを「要素」と呼ぶ- 各要素には「インデックス番号」という0から始まる連番が割り振られている
students[0]
のように、インデックス番号を指定することでそれに応じた値を取得できる
このような特徴がありました。
これに対して、オブジェクト(連想配列)は以下のような書き方をします。
const students = {'A01': 'sato', 'A02': 'suzuki', 'A03': 'takahashi'};
console.log(students['A01']);
オブジェクトの特徴としては、
- ブレイス
{ }
で定義する { }
の中のデータのことを「キーと値」とか「keyとvalue」と呼ぶ- キーと値のペアのことを「プロパティ」と呼ぶ
students['A01']
のように、キーを指定することでそれに応じた値を取得できる
このような特徴があります。
以下、配列とオブジェクト(連想配列)それぞれの値取得の方法を比較してみましょう。
①配列から値を取得する場合、ブラケット[ ]
の中に「インデックス番号」を指定する
②オブジェクト(連想配列)から値を取得する場合、ブラケット[ ]
の中に「キー」を指定する
いかがでしょうか。こうしてみると配列とオブジェクト(連想配列)はよく似ていますね。
いずれも複数のデータを扱うという点では共通しています。
配列の「インデックス番号」に相当するものが、オブジェクトにおける「キー」だと考えるとわかりやすいでしょうか。
実際は単数系の情報を扱うことが多い
さて、まずは配列と比較しながら学んでもらうために、satoさん、suzukiさん、takahashiさんの3人の「students」という複数形のオブジェクトを例示しましたが、実際はこのような複数形の情報をオブジェクトで使うことはあまりありません。
実際は次のように、satoさん1人に焦点をあてた「student」のような単数系の情報を管理するときに使うことが多いです。
const student = {'id': 'A01', 'name': 'sato'};
この例では、satoさんの「ID(id)」と「名前(name)」という、1人の生徒の情報についてのオブジェクトを生成しています。
「ID」と「名前」以外の情報も詰め込んでみましょう。
const student = {
'id': 'A01',
'name': 'sato',
'age': 18,
'gender': 'male',
'liveIn': 'Tokyo',
'club': 'soccer',
'hobby': 'game',
};
「ID」「名前」に加えて、「年齢(age)」「性別(gender)」「住所(liveIn)」「部活(club)」「趣味(hobby)」の情報を追加しました。
このように、情報が増える場合は改行して書くと読みやすいですね。
キーのクォートは省略できる
もうひとつオブジェクトの特徴を紹介します。
「キーと値」における「キー」に注目してください。
const student = {
'id': 'A01',
'name': 'sato',
'age': 18,
'gender': 'male',
'liveIn': 'Tokyo',
'club': 'soccer',
'hobby': 'game',
};
こちらでは'id'
や'name'
のように、文字がシングルクォートで囲われており、キーが「文字列型」で指定されていますが、以下のようにクォートを省略することもできます。
const student = {
id: 'A01',
name: 'sato',
age: 18,
gender: 'male',
liveIn: 'Tokyo',
club: 'soccer',
hobby: 'game',
};
こちらではクォートが省略され、キーが「文字列型」ではなくなりました。
こちらの書き方のほうが可読性が上がる(読みやすくなる)ため、一般的にはこの書き方を推奨されることが多いです。
しかし、この書き方をする場合は、ハイフンやスペースなどの特殊文字を使うことができません。
// こういう書き方はエラーになります
const student = {
first-name: 'yuki',
last-name: 'sato',
live in: 'Tokyo',
};
このようにキーに特殊文字を含める必要がある場合は、シングルクォート(またはダブルクォート)をつけて文字列型にしてあげましょう。
// これならエラーになりません
const student = {
'first-name': 'yuki',
'last-name': 'sato',
'live in': 'Tokyo',
};
これならエラーになりません。
ただし、これはあまり推奨できる書き方ではありません。
可読性の観点から、できるかぎりクォートなしでかけるように設計することをオススメします。
ブラケット記法とドット記法
ブラケット記法
さて、オブジェクトにおける値を取得する場合は、student['id']
のようにすれば、そのキーに応じた値を取得できるという話を最初にしました。
試しに以下のコードを実行してみます。
function myFunction() {
const student = {
'id': 'A01',
'name': 'sato',
'age': 18,
'gender': 'male',
'liveIn': 'Tokyo',
'club': 'soccer',
'hobby': 'game',
};
console.log(student['id']);
console.log(student['name']);
}
こちらを実行すると、以下のような結果となります。
それぞれのキーに応じた値を取得できているのが確認できますね。
このように、オブジェクトに対してブラケット[ ]
を使って、そのブラケットの中にキーを指定する方法を「ブラケット記法」といいます。
このブラケット記法は、キーのクォートを省略する書き方でも同じように使うことができます。
function myFunction() {
const student = {
id: 'A01',
name: 'sato',
age: 18,
gender: 'male',
liveIn: 'Tokyo',
club: 'soccer',
hobby: 'game',
};
console.log(student['id']);
console.log(student['name']);
}
こちら実行してみましょう。
この際の注意点としては、オブジェクトの定義部分ではクォートを省略した書き方になっていますが、値を取得する際のブラケットの中ではクォートを省略できないというところです。
もし値を取得する部分でクォートを省略してしまうと、以下のようにエラーとなります。
このように、ブラケットの中でクォートを省略してしまうと、idが変数として識別されてしまいますので、「ReferenceError: id is not defined」というエラーが吐き出されてしまうのです。
しかし、オブジェクトの定義部分ではクォート省略できるのに、値を取り出すときは省略できないというのは、なんだか気持ち悪いですね。書き方に統一性がないので、違和感があります。
ドット記法
そこで、ドット記法の出番です。
ブラケット記法ではオブジェクト['キー']
という書き方で値を取得したのに対して、
ドット記法ではオブジェクト.キー
とすることで値を取得することができます。
以下のサンプルを実行してみましょう。
function myFunction() {
const student = {
id: 'A01',
name: 'sato',
age: 18,
gender: 'male',
liveIn: 'Tokyo',
club: 'soccer',
hobby: 'game',
};
console.log(student.id);
console.log(student.name);
}
こちらを実行すると、以下のように値取得することができました。
これだったらクォートを省略できるので、書き方に統一性が出て、読みやすくなりますね。
基本的にはドット記法推奨
このように、JavaScriptのオブジェクトで値を取得する際は、
- ブラケット記法
- ドット記法
という2つの書き方が用意されています。
一般的にはドット記法のほうが読みやすいとされているため、なるべくドット記法を使うことが推奨されますが、状況によってはブラケット記法を使わざるを得ないこともあります。
たとえば、キーに特殊文字(スペースやハイフンなど)が含まれている場合は、ブラケット記法しか使えません。
また、以下のようにキーが変数化されている場合も、ブラケット記法しか使えません。
このような状況でない限りは、なるべくドット記法を使うように心がけましょう。
ブラケット記法とドット記法、どちらもGAS(JavaScript)でプログラミングをする上では、必要不可欠な知識となりますので、しっかり理解しておきましょう。
オブジェクトの階層化
次にオブジェクトの階層化について説明します。
オブジェクトの階層化とは、オブジェクトの中にさらにオブジェクトをネストして構造化することです。
こんな説明をすると小難しそうに聞こえてしまいますが、なんてことはありません。オブジェクトの中にさらにオブジェクトがあるというだけです。
次のサンプルコードの4〜8行目にご注目ください。
function myFunction() {
const student = {
name: 'sato',
birthday: {
year: 2006,
month: 6,
day: 1
},
age: 18,
};
console.log(student.birthday.year);
console.log(student.birthday.month);
console.log(student.birthday.day);
}
birthday
というキーに対して、その値は{year: 2006, month: 6, day: 1}
というオブジェクトになっています。
こうすることで、「誕生日」という情報を「年」「月」「日」というさらに細かい情報に分けて整理することができます。
値を取得するときはstudent.birthday.year
のようにキーをドットでつないでいくだけです。
ドット記法で書くと綺麗に書けますし、コードの意味もわかりやすいですね。
ちなみにドット記法ではなく、ブラケット記法で書くことも可能です。
その場合student['birthday']['year']
のように書きますが、やっぱりドット記法の方が書きやすいし読みやすいですよね。
メソッド
さて、オブジェクトの説明の最後に、メソッドについて説明しておきましょう。
オブジェクト同様、メソッドという言葉もこれまで何の説明もなくしれっと使ってましたが、ここでようやく説明ができます。
メソッドとは、ズバリひとことでいうと「オブジェクトの中で定義された関数」のことです。
まずは以下のサンプルコードをご覧ください。
function myFunction() {
const student = {
name: 'sato',
birthday: {
year: 2006,
month: 6,
day: 1
},
age: 18,
};
}
こちらのオブジェクトについて、現状は問題点があります。
それは、年齢の管理方法です。現状はage: 18
となっていますが、これって年々変わっていく数字ですよね。
このままでは誕生日を迎えるたびに手動でデータを書き換えなければなりません。
そこで、このオブジェクトを以下のように書き換えます。
function myFunction() {
const student = {
name: 'sato',
birthday: {
year: 2006,
month: 6,
day: 1
},
getAge: function() {
const now = new Date();
const birthday = new Date(now.getFullYear(), this.birthday.month-1, this.birthday.day);
let age = now.getFullYear() - this.birthday.year;
if(now < birthday) age--;
return age;
}
};
console.log(student.getAge());
}
age
の代わりにgetAge
というキーを用意して、それに対応する値はfunction
としました。
function、つまり関数です。関数とは、「一連の処理をひとまとめにしたもの」でしたね。
では、その一連の処理はどういう内容になっているかというと、「現在日時と誕生日の差分を計算して、現在の年齢を取得する」という内容になっています。
※この処理の中身についての解説はここではしませんので、気になる人は自分で調べてみてください。
このように、オブジェクトの中で定義された関数のことを「メソッド」と呼ぶのです。
では、実際にgetAgeメソッドを呼び出してみましょう。
メソッドは、オブジェクト.メソッド()
というように、オブジェクトに対してドット記法でメソッド名を記述し、最後に()
をつけることで呼び出すことができます。
今回の場合、student.getAge()
とすることでgetAgeメソッドを呼び出すことができます。
出力結果は「18」となりました。
この記事を書いている現在は2024年8月19日で、誕生日は2006年6月1日に設定してるので、計算は合ってそうですね。
念の為、誕生日を2006年8月20日に変えて実行してみます。
すると無事、「17」と出力されたので、現在日時に応じて年齢を算出できているということが確認できました。
いかがでしょうか。これまで何気なく使っていたメソッドという言葉について、その仕組みを何となく理解できたでしょうか?
メソッドという言葉はこれまで何度も出てきていました。
ss.getSheetByName('集計')
のgetSheetByNameメソッドsheet.getRange('A1')
のgetRangeメソッドsheet.getLastRow()
のgetLastRowメソッド
などなど、幾度となく出てきていましたよね。
今見たらわかると思いますが、これらはすべてオブジェクト.メソッド()
という形になっています。
「ss」はスプレッドシートファイルを指すオブジェクトですし、「sheet」はスプレッドシートの中の1枚のシートを指すオブジェクトです。
これまでよく分からず書いていたコードは、実はすべてオブジェクトとメソッドで成り立っていたんですね。
まとめ
以上、オブジェクトとメソッドについて解説しました。
これまで何気なく使っていた「オブジェクト」や「メソッド」という言葉について、ようやく説明することができました。
このように、プログラミング用語はある程度学習が進んでからでないと説明できない言葉がたくさんあります。
途中までは意味がよく分からないまま学習を進めなければならず、その期間はモヤモヤした状態が続くので釈然としないですよね。しかし、言葉の意味が理解できた瞬間は霧が晴れたように、鮮明な景色が見えてくると思います。
点と点だった知識が一つの線になる瞬間は、伏線が張り巡らされたミステリー小説の壮大な種明かしの瞬間に似ています。そういった刺激的な体験ができるのも、プログラミング学習の楽しさだと思います。
このタイミングで改めて第1回の記事から読み直してみると、最初はよくわからなかったぼんやりとした概念が、輪郭がくっきりして見えてくるのではないでしょうか。余裕のある人はぜひ復習してみてください。
次回は今回学んだ知識を活用して、応用問題の解答をリファクタリングしていきます!
連載目次: GASでスプレッドシートを自由自在に操るためのスキル習得講座
- 【GASの始め方】まずはスプレッドシートの操作から始めてみよう
- 【GASの始め方】setValuesで複数のセルに値を入力しよう
- 【GASの始め方】getValueで値を取得してsetValueで入力しよう
- 【GASの始め方】getValuesで複数のセルの値を取得しよう
- 【GASの始め方】getValuesして別のシートにsetValuesしよう
- 【GASの始め方】応用問題で関数について学ぼう
- 【GASの始め方】繰り返し処理の「for文」を習得しよう
- 【GASの始め方】flat()でループさせる配列を自動生成しよう
- 【GASの始め方】for文とif文でデータ抽出して配列を生成しよう
- 【GASの始め方】TextFinderで行と列を特定しよう
- 【GASの始め方】オブジェクトとメソッドについて学ぼう
- 【GASの始め方】リファクタリングで生成AIを活用しよう
Udemy動画解説
当シリーズはUdemyで動画解説をしています。
動画で学びたい方は以下からご購読ください。Udemyでは月2〜3回セールが開かれますので、セール期間中にご購入いただくのがオススメです。
コメント