オブジェクトってどうやって作るの?
プロパティやメソッドの使い方がわからない
オブジェクトってJSONや配列に変換できるの?
JavaScriptを学習するにあたり、必ず出てくるキーワードとして「オブジェクト」があります。このオブジェクトの概念やどのように扱えば良いのかよく分からないという人も多いのではないでしょうか。
配列よりもさらに複雑なデータ構造を保持するのにオブジェクトは必須のスキルでもあり、JavaScriptを活用するうえで避けては通れません。
そこで、この記事では初心者でもオブジェクトの使い方や活用方法について具体例と共に分かりやすく解説していきます。記事後半ではオブジェクトの活用法として、実際によく使われるJSONへの変換手順なども解説していますので、ぜひ参考にしてみてください。
JavaScriptのオブジェクトとは?
JavaScriptにはデータを格納する手段として「変数」「配列」などがありますが、本記事で学習するオブジェクトもその1つです。
変数は1つのデータしか格納できませんが、配列はさまざまな型のデータを複数格納できるのが特徴です。それではオブジェクトにはどんな特徴があるのでしょうか。
そこで、例として会員ユーザーのデータを配列で格納したコードを見てください。
const array = ['free','田中太郎',30];
上記コードを見ると、「田中太郎」が名前を意味しているのはなんとなく分かりますが、「free」「30」は何を指しているのか分かりづらいですよね。
まったく同じ内容を、今度はオブジェクトで記述すると以下のようになります。
const obj = { plan: 'free', name: '田中太郎', age: 30 }
上記コードを見ると、「free」はユーザーが選択しているプランであり、「30」は年齢であることがプログラムを見ただけで理解できますね。
このようにオブジェクトは「名前:値」というペアでさまざまなデータを格納できるため、複雑な構造をしたデータをJavaScriptで扱う時に最適なわけです。また、オブジェクトには「名前:関数」というペアでデータを格納することもできます。
オブジェクトの世界では、これらのペアを「プロパティ」「メソッド」と呼んでいます。
・「名前:値」→プロパティ
・「名前:関数」→メソッド
プロパティやメソッドの詳しい使い方については、次の章から解説していきますのでぜひ参考にしてみてください。
オブジェクトの作成と初期化
この章では、基本的なオブジェクトを作成する方法について見ていきましょう! 主に、リテラルやnew演算子を使った作成方法を学んでいきます。
基本的なオブジェクトの作り方
一般的なオブジェクトの作り方としては{ }を利用して以下のように記述します。
const myObject = {};
この1行で新しいオブジェクトを作成することができます。
また、上記のコードではデータが何もない空っぽのオブジェクトを作成しているので、オブジェクトの初期化処理とも言われます。
new演算子を使う方法
もう1つの作り方としては、new演算子を利用したパターンがあります。
const myObject = new Object();
newを使うとObjectのインスタンス(コピーのようなもの)を作ることができます。なので、myObjectとObjectは別のモノとして扱われます。
ちなみに、インスタンスの概念やnewの基本的な使い方については、次の記事で体系的にまとめているのでぜひ参考にしてみてください!
プロパティの作り方
この章では、オブジェクト内に含めるプロパティの作り方について見ていきましょう! 主に、基本的なプロパティの構文や配列の中に作るオブジェクトについても学習していきます。
基本的なプロパティの構文
まずは基本的なプロパティを作ってみましょう!
記述方法は「キー(プロパティ名)」と「値」がペアになるようにします。
プロパティ名 : 値
「値」に関しては文字列や数値だけでなくBoolean型・配列・関数…など、JavaScriptで扱うほとんどの値を設定することができます。
const info = { name : '田中 太郎', age : 30, japan: true, hobby: ['読書', 'ウォーキング', 音楽''], getName: function() { console.log(this.name) } }
プロパティにアクセスする方法
作成したプロパティをプログラムからアクセスする方法について解説しておきます。
一般的にはドット演算子(「.」)を使う方法とブラケット記述法([])があります。
ドット演算子を使う場合は、オブジェクト名とプロパティ名を「.」で連結させて使います。次の例を見てください。
const user = { name : '田中太郎', age : 30 } console.log(user.name + ', ' + user.age);
実行結果
田中太郎, 30
「user.name」と記述することでオブジェクトの「name」プロパティにアクセスできており、値の「田中太郎」を取得できたのが分かります。
同じ内容を今度はブラケット記述法でも試してみましょう。
この記述法では、「.」を使うのではなく配列のように[ ]で囲んだ中にプロパティ名を記述します。次のサンプル例を見てください。
const user = { name : '田中 太郎', age : 30 } console.log(user['name'] + ', ' + user['age']);
実行結果
田中 太郎, 30
「user[‘name’]」と記述することでnameプロパティにアクセスできているのが分かりますね。
基本的にはドット演算子を利用することが多いのですが、プロパティ名を日本語にした場合などはブラケット記述法でないとアクセスできないのでどちらも使えるように慣れておきましょう。
配列の中にオブジェクトを作る
オブジェクト自体を配列の要素にすることもできるので、合わせて解説しておきます! 次のサンプル例を見てください!
const arr = [ {name: '太郎', age: 30}, {name: '花子', age: 25}, {name: '次郎', age: 42} ];
この例では、配列の要素1つずつがオブジェクトになっていることが分かります。各オブジェクトの中には「name」「age」という2つのプロパティが存在していますね。
このように配列の要素としても利用できるのはオブジェクト自体も値として利用することができるからです。そのため、例えばプロパティの値に別のオブジェクトを設定して階層構造を持たせることも可能です。
const info = { name : '田中 太郎', age : 30, hobby: { book: 'Sample Book', music: 'myMusic Song' }, }
この例では、オブジェクトの中にある「hobby」プロパティの中で、さらに「book / music」というプロパティを作成しています。
プロパティの操作
プロパティの追加
プロパティはあとから追加していくこともできます。ドット演算子(「.」)を使う方法とブラケット記述法([])のどちらでもできます。
const info = { name : '田中 太郎', } info.age = 30; info['add'] = "東京千代田区"; console.log(info);
実行結果:
{name: "田中 太郎", age: 30, add: "東京千代田区"}
プロパティの削除
delete演算子を使ってプロパティを削除することができます。
const info = { name : '田中 太郎', age : 30, add : "東京千代田区" } delete info.add; console.log(info);
実行結果:
{name: "田中 太郎", age: 30}
プロパティの存在チェック
指定したプロパティが存在しているかどうかを確認する方法として、「undefined」「in」を使う方法がありますので解説をしておきます。
undefinedと比較
JavaScriptでは存在しないプロパティにアクセスした場合にundefinedを返します。例外が発生するわけではありません。
次のサンプル例を見てください。
const info = { name : '田中 太郎', age : 30, } if (info.add == undefined) { console.log('プロパティaddは存在しません'); }
実行結果:
プロパティaddは存在しません
上記のコードでは、「add」プロパティが存在するかどうかをundefinedで比較しています。存在しなければundefinedが返るので結果は「true」となり、指定した文字列がコンソールログに出力されるわけです。
in演算子を使う方法
in演算子は指定したプロパティが存在する場合にtrueを返す特徴があります。
次のサンプル例を見てください。
const info = { name : '田中 太郎', age : 30, } const check = 'add' in info; if (check) { console.log('プロパティaddは存在します'); } else { console.log('プロパティaddは存在しません'); }
実行結果:
プロパティaddは存在しません
上記サンプルでは「’add’ in info」のように記述することで、「add」プロパティが存在するかどうかを確認しています。実際には存在していないので返り値としては「false」になります。
つまり、IF文の「false」処理が実行されるというわけです。
メソッドの作り方
この章では、基本的なメソッドの作り方について見ていきましょう! 主に、メソッド構文の概要とthisの扱いについて学んでいきます。
基本的なメソッドの構文
冒頭でも少し紹介しましたが、メソッドはプロパティの値に関数を設定したものというのが基本的な考え方になります。
const obj = { //プロパティ : 値(文字・数値・配列など), //プロパティ : 関数 ←これがメソッド }
例えば、文字列をコンソールログに出力するだけのメソッドは次のように作成することができます。
const obj = { showText: function() { console.log( 'Hello World' ); } }
この例では、objというオブジェクトにshowTextという名前のメソッドを作成しています。メソッドの作り方は一般的な関数を作成する方法とほとんど同じと言えるでしょう。
メソッドにアクセスする方法
今度は作成したメソッドを実行する方法について解説をしておきます。
先ほど作成した例をもう一度見てください。
const obj = { showText: function() { console.log( 'Hello World' ); } }
上記コードの場合、メソッドは「showText()」になります。
実行するにはドット演算子を利用して次のように記述します。
obj.showText()
実行結果
Hello World
上記コードのようにオブジェクト名に続けてメソッド名を「.」で連結すれば実行できるわけです。
ちなみに、メソッドの基本から活用術を次の記事で詳しくまとめているので、ぜひ合わせて参考にしてみてください!
thisのスコープについて
thisはJavaScriptに最初から用意されている変数で、呼び出した場所や方法によってその中身が変化するという特殊な存在です。これはメソッドとして使う場合と、一般的な関数として使う場合でも異なってくるので解説をしておきます。
例えば、次のサンプル例を見てください!
const myObj = { getSomething: function() { console.log( this ); function showSomething() { console.log( this ); } } };
この例では、getSomethingというメソッドを作成していますね。このメソッドの中で、一般的な関数showSomethingを作っている点にも注目してください。
このメソッドと関数は、それぞれthisをコンソールログに出力する処理を記述しています。しかしながら、この実行結果はどちらも同じではありません。結果は以下のようになります!
- メソッドのthis:自身のオブジェクトを出力する
- 関数のthis:windowsオブジェクトを出力する
つまり、メソッド呼び出しと関数呼び出しではthisの示す内容が異なります。この事実を知らないと、バグを引き起こす可能性があるので十分に注意しておきましょう。
オブジェクトをループしてプロパティを取得する
オブジェクトが持つプロパティをすべて列挙する方法をご紹介します。一般的な方法として「Object.keys()」「forEach()」「for-in()」について学んでいきます。
Object.keys()を使ってプロパティを取得する方法
まずは、「Object.keys()」を使った方法を見ていきましょう! これは引数に任意のオブジェクトを指定するだけで、保持しているプロパティを列挙してくれるので便利です。次のサンプル例を見て下さい!
const obj = { name : '田中 太郎', age : 30, area : '東京都千代田区' } console.log(Object.keys(obj));
["name", "age", "area"]
この例では、「Object.keys()」の引数に「obj」を指定することでプロパティだけを列挙しているのが分かりますね。また、戻り値が「配列」になるという点もポイントです。
forEach()を使ってプロパティを取得する方法
今度は「forEach()」を使った方法を見てましょう! ただし、forEach()は「配列」に対して利用できるメソッドなので、このままではオブジェクトに使うことができません。
しかし、思い出して下さい! 「Object.keys()」を使えば配列としてプロパティを取得できましたよね? そこで、次のような記述でプロパティの名称を列挙できます。
Object.keys(obj).forEach(function(value) { console.log(value); });
name age area
この例では、Object.keys()に続けてforEach()をチェーンで繋いで実行しています。このように記述することで、オブジェクトのプロパティを配列化したあとにforEach()で1つずつ処理しているわけです。
これにより、保持しているプロパティを活用した複雑な処理も可能になるわけです。
for-inを使ってプロパティを取得する方法
一般的によく使われる「for-in」を使った方法についても見ていきましょう! これはfor文のようにオブジェクトが持つプロパティを1つずつ繰り返し取得することができます。次のサンプル例を見て下さい!
const obj = { name : '田中 太郎', age : 30, area : '東京都千代田区' } for (let key in obj) { console.log(key); }
name age area
この例では、オブジェクト「obj」に対してプロパティを1つずつ「key」という値に代入して取得しています。
ただし、for-inの特性としてプロトタイプチェーンを辿ってプロパティすべてを列挙します。この特性を使いたくない場合は、以下のように「hasOwnProperty()」を使うようにしましょう!
for (let key in obj) { if(obj.hasOwnProperty(key)){ console.log(key); } }
オブジェクト「obj」に対して「hasOwnProperty()」を使い、引数にプロパティが代入された「key」を指定すればOKです。
オブジェクトの活用
この章では、オブジェクトをさらに活用するための方法について見ていきましょう! 主に、オブジェクトをJSONや配列に変換する方法や複製について学んでいきます。
「JSON.stringify()」でオブジェクトをJSONに変換する
オブジェクトをJSONに変換するには「JSON.stringify()」を利用します。これは引数にオブジェクトを指定するだけで、戻り値としてJSONデータを取得することができるのです。次のサンプル例を見て下さい!
const obj = { name : '田中 太郎', age : 30, area : '東京都千代田区' } const result = JSON.stringify(obj); console.log(result);
{"name":"田中 太郎","age":30,"area":"東京都千代田区"}
この例では、「JSON.stringify()」の引数にオブジェクト「obj」を指定しています。実行結果を見ても分かるようにオブジェクトのデータがJSONに変換されて文字列として取得できているわけです。
この「JSON.stringify()」についての活用方法は次の記事で体系的にまとめているので、ぜひ参考にしてみてください!
「Object.values()」でオブジェクトを配列に変換する
次に、オブジェクトを配列に変換する方法について見ていきましょう! 基本的に配列とオブジェクトはデータの構造が違うわけですが、「Object.values()」を使うとプロパティの「値」を配列化できます。使い方は簡単でvalues()の引数に配列化したいオブジェクトを指定するだけです!
Object.values(【オブジェクト】)
引数に指定したオブジェクトの「値」を自動的に抽出して、配列の要素に書き出してくれます。次のサンプル例を見てください!
const obj = { name: 'taro', age: 30, area: 'Tokyo' } const result = Object.values(obj); console.log(result);
["taro", 30, "Tokyo"]
この例では、「name / age / area」という3つのプロパティの「値」を配列にしています。実行結果を見ると「値」だけが配列要素に変換されているが分かりますね。
「Object.assign()」でオブジェクトを複製する
今度はオブジェクトを複製する方法を見ていきましょう! まずは、簡単なオブジェクトを用意します。
const obj = { name: 'taro', age: 30 }
この例では、名前と年齢だけのプロパティを持っています。普通に考えればオブジェクトの複製は次のように記述すれば問題ないように思えます。
const newObj = obj; console.log(obj); console.log(newObj);
{ name: "taro", age: 30 } { name: "taro", age: 30 }
「obj」の複製として新しく「newObj」というオブジェクトを複製して、実行結果も問題ないように見えますよね? しかし、例えば値を変更してみると問題が発生するのが分かります!
obj.name = 'hanako'; console.log(obj); console.log(newObj);
{ name: "hanako", age: 30 } { name: "hanako", age: 30 }
「obj」のnameプロパティを変更したわけですが、実行結果を見ると「newObj」のnameプロパティも一緒に変更されてしまっているのが分かります。実は、単純に「const newObj = obj」と記述しただけでは複製とは言えず、あくまで「obj」を参照しているだけにすぎないのです。
そのため、「obj」の値が変更されると参照している「newObj」の値も変わるわけです。そこで、利用するのが「Object.assign()」です!
Object.assign(【複製オブジェクト】, 【複製元オブジェクト】);
このように、複製するオブジェクトと複製元になるオブジェクトを指定するだけで参照ではない完全なコピーを作ることができるのです。次のサンプル例を見てください!
const newObj = Object.assign({}, obj); obj.name = 'hanako'; console.log(obj); console.log(newObj);
{ name: "hanako", age: 30 } { name: "taro", age: 30 }
この例では、複製元として「obj」を指定し、複製するオブジェクトは新規で作るため{ }のように空のオブジェクトを設定します。これにより、「obj」の値だけを変更すれば複製されたnewObjの値は変更していないのが実行結果からも分かりますね!
まとめ
ここでは、オブジェクトや独自オブジェクトの作り方について説明しました。オブジェクトとは、モノの特徴を表すプロパティの集まりのことです。
ブラウザにあらかじめ用意されたオブジェクトもあれば、独自のオブジェクトを作成することもできます。使いこなすことができるように、この記事を何度も参考にして下さいね!