JavaScriptには、numberやstringのようなプリミティブ型のデータ型のほかに、objectと呼ばれる重要なデータ型があります。
オブジェクトは、キーと値のペアの集まりです。
そのため、他の言語でマップや辞書と呼ばれるものと同じように使うことができます。
他の言語では、マップの中のすべての値が同じデータ型である必要があることがよくあります。
JavaScriptでは、キーの型だけが制限され、stringでなければなりません。
1つのオブジェクトの中の値は、それぞれ異なる型を持つことができます。
値には、数値のようなプリミティブ型だけでなく、配列、他のオブジェクト、さらには関数を使うこともできます。
このようにオブジェクトは非常に汎用性が高く、JavaScriptにおけるオブジェクト指向プログラミング(OOP)の中心的な存在でもあります。
ここからは、オブジェクトをコレクションやマップとして扱うことに焦点を当てます。 オブジェクトのその他の用途については、別のコンセプトで扱います。例えばクラスを参照してください。
オブジェクトは波括弧({})を使って作成します。
いくつかのエントリを直接含めることもできます。
その場合は、まずキーを書き、その後にコロンと値を続けます。
const emptyObject = {};
const obj = {
favoriteNumber: 42,
greeting: 'Hello World',
useGreeting: true,
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
fruits: ['melon', 'papaya'],
addNumbers: function (a, b) {
return a + b;
},
};
JavaScriptでは、最後のエントリのあとのカンマは省略できます。
キーは文字列であるはずなのに、なぜ引用符で囲まれていないのか不思議に思うかもしれません。 これは省略記法です。 キーがJavaScriptの識別子の命名規則に従っていれば、引用符を省略できます。 名前に特殊文字を含むキーの場合は、通常の文字列の記法を使う必要があります。
const obj = {
'1keyStartsWithNumber': '...',
'key/with/slashes': '...',
'key-with-dashes': '...',
'key with spaces': '...',
'#&()[]{}èä樹keyWithSpecialChars': '...',
};
あるキーの値を取得する方法は2つあります。ドット記法とブラケット記法です。
const obj = { greeting: 'hello world' };
obj.greeting;
// => hello world
obj['greeting'];
// => hello world
// Bracket notation also works with variables.
const key = 'greeting';
obj[key];
// => hello world
省略記法としてのドット記法を使う場合も、引用符を省略する場合と同じ制限があります。 キーが識別子の命名規則に従っている場合にのみ使えます。
代入演算子=を使うと、値を追加したり変更したりできます。
ここでも、ドット記法とブラケット記法が使えます。
const obj = { greeting: 'hello world' };
obj.greeting = 'Hi there!';
obj['greeting'] = 'Welcome.';
obj.newKey1 = 'new value 1';
obj['new key 2'] = 'new value 2';
const key = 'new key 3';
obj[key] = 'new value 3';
deleteキーワードを使うと、オブジェクトからキーと値のペアを削除できます。
const obj = {
key1: 'value1',
key2: 'value2',
};
delete obj.key1;
delete obj['key2'];
hasOwnPropertyメソッドを使うと、あるキーがオブジェクトに存在するかどうかを確認できます。
const obj = { greeting: 'hello world' };
obj.hasOwnProperty('greeting');
// => true
obj.hasOwnProperty('age');
// => false
オブジェクトのすべてのキーを繰り返し処理するための、特別なfor...inループがあります。
const obj = {
name: 'Ali',
age: 65,
};
for (let key in obj) {
console.log(key, obj[key]);
}
// name Ali
// age 65
微妙なエラーを避けるために、for...inループはキーを任意の順序でたどるものと常に考えるようにしましょう。
また、for...inは繰り返しの中に継承されたキーを含むことにも注意してください。
この演習では、地元のゲームセンターで一番人気のゲームのハイスコアを記録する仕組みを実装します。
実装する関数は5つあり、そのほとんどはハイスコアを保持するオブジェクトの操作に関係しています。
ハイスコアボードとして機能するオブジェクトを作るcreateScoreBoard関数を作成します。
このオブジェクトのキーはプレイヤーの名前で、値はそのスコアになります。
テストのために、あらかじめオブジェクトに1件のエントリーを含めておきます。
この最初のエントリーは、プレイヤー名をThe Best Ever、スコアを1000000にします。
createScoreBoard();
// returns an object with one initial entry
ハイスコアボードにプレイヤーを追加するには、addPlayer関数を定義します。
この関数は3つの入力を受け取ります。
この関数は、新しいプレイヤーを追加したあと、渡されたのと同じスコアボードのオブジェクトを返します。
addPlayer({ 'Dave Thomas': 0 }, 'José Valim', 486373);
// => {'Dave Thomas': 0, 'José Valim': 486373}
プレイヤーがゲームセンターのルールに違反すると、そのプレイヤーはハイスコアボードから手動で削除されます。
removePlayerを定義します。この関数は2つの入力を受け取ります。
この関数は、指定されたプレイヤーのエントリーをボードから削除し、そのあとボードを返します。 そのプレイヤーがそもそもボードにいなかった場合は、ボードに何も起こりません。 ボードはそのまま返します。
removePlayer({ 'Dave Thomas': 0 }, 'Dave Thomas');
// => {}
removePlayer({ 'Dave Thomas': 0 }, 'Rose Fanaras');
// => { 'Dave Thomas': 0 }
プレイヤーがゲームセンターでもう1ゲームを終えると、一定のポイントがボード上の前回のスコアに加算されます。
updateScoreを実装します。この関数は3つの入力を受け取ります。
この関数は、更新が終わったあとのスコアボードを返します。
updateScore({ 'Freyja Ćirić': 12771008 }, 'Freyja Ćirić', 73);
// => {"Freyja Ćirić", 12771081}
ゲームセンターでは、月曜日に別のスコアボードを使います。 1日の終わりに、そのボードに載っている各プレイヤーが100ポイントを追加で受け取ります。
スコアボードを受け取るapplyMondayBonus関数を実装します。
この関数は、そのボードに載っている各プレイヤーにボーナスポイントを加算します。
そのあと、ボードを返します。
const scoreBoard = {
'Dave Thomas': 44,
'Freyja Ćirić': 539,
'José Valim': 265,
};
applyMondayBonus(scoreBoard);
// => { 'Dave Thomas': 144, 'Freyja Ćirić': 639, 'José Valim': 365 }
Exercismに登録すれば、37個のコンセプト159個の演習、そして本物の人間によるメンタリングとともに、JavaScriptを学んでマスターできます。すべて無料です。