「データ型」の章からわかるように、JavaScript には 8 つのデータ型があります。そのうちの 7 つは「プリミティブ」と呼ばれます。その値には 1 つのもの (文字列、数値、その他) しか含まれていないためです。
対照的に、オブジェクトは、さまざまなデータやより複雑なエンティティのキー付きコレクションを格納するために使用されます。 JavaScript では、オブジェクトは言語のほぼすべての側面に浸透します。したがって、他の部分について詳しく説明する前に、まずそれらを理解する必要があります。
オブジェクトは、オプションのプロパティのリストを使用して図括弧{…}
を使用して作成できます。プロパティは「キー:値」のペアであり、 key
は文字列 (「プロパティ名」とも呼ばれます)、 value
任意の値にすることができます。
オブジェクトは、署名されたファイルが入ったキャビネットとして想像できます。すべてのデータはキーによってファイルに保存されます。ファイルを名前で検索したり、ファイルを追加/削除したりするのは簡単です。
空のオブジェクト (「空のキャビネット」) は、次の 2 つの構文のいずれかを使用して作成できます。
let user = new Object(); // 「オブジェクト コンストラクター」の構文 ユーザー = {} にします。 // 「オブジェクトリテラル」構文
通常は、数字括弧{...}
が使用されます。この宣言はオブジェクト リテラルと呼ばれます。
いくつかのプロパティを「キー: 値」のペアとして{...}
にすぐに入れることができます。
let user = { // オブジェクト name: "John", // キー "name" によって値 "John" を格納します age: 30 // キー「age」により値 30 を格納します };
プロパティには、コロン":"
の前にキー (「名前」または「識別子」とも呼ばれます) があり、その右側に値があります。
user
オブジェクトには、次の 2 つのプロパティがあります。
最初のプロパティの名前は"name"
、値は"John"
です。
2 番目の名前は"age"
、値は30
です。
結果として得られるuser
オブジェクトは、「名前」と「年齢」というラベルが付けられた 2 つの署名付きファイルが入ったキャビネットとして想像できます。
いつでもファイルを追加、削除、読み取りできます。
プロパティ値にはドット表記を使用してアクセスできます。
// オブジェクトのプロパティ値を取得します。 アラート( ユーザー名 ); // ジョン アラート( user.age ); // 30
値は任意の型にすることができます。ブール値を追加しましょう。
user.isAdmin = true;
プロパティを削除するには、 delete
演算子を使用できます。
user.age を削除します。
複数語のプロパティ名を使用することもできますが、その場合は引用符で囲む必要があります。
ユーザー = { にします 名前:「ジョン」、 年齢:30歳、 "likes Birds": true // 複数語のプロパティ名は引用符で囲む必要があります };
リストの最後のプロパティはカンマで終わる場合があります。
ユーザー = { にします 名前:「ジョン」、 年齢:30歳、 }
これは、「末尾」または「ぶら下がり」コンマと呼ばれます。すべての行が同じになるため、プロパティの追加/削除/移動が簡単になります。
マルチワード プロパティの場合、ドット アクセスは機能しません。
// これは構文エラーになります user.likes 鳥 = true
JavaScript はそれを理解できません。 user.likes
に対応していると考えており、予期しないbirds
に遭遇すると構文エラーが発生します。
ドットを使用するには、キーが有効な変数識別子である必要があります。これは、スペースが含まれておらず、数字で始まらず、特殊文字も含まれていないことを意味します ( $
と_
使用できます)。
任意の文字列で機能する代替の「角括弧表記」があります。
ユーザー = {} にします。 // セット user["鳥が好き"] = true; // 得る alert(user["鳥が好き"]); // 真実 // 消去 ユーザーを削除[「鳥が好き」];
今はすべて順調です。括弧内の文字列は適切に引用符で囲まれていることに注意してください (任意の種類の引用符を使用できます)。
角括弧は、リテラル文字列ではなく、次のように変数からなど、任意の式の結果としてプロパティ名を取得する方法も提供します。
let key = "鳥が好き"; // user["likesbird"] = true; と同じです。 ユーザー[キー] = true;
ここで、変数key
実行時に計算されることも、ユーザー入力に依存することもあります。そして、それを使用してプロパティにアクセスします。これにより、大きな柔軟性が得られます。
例えば:
ユーザー = { にします 名前:「ジョン」、 年齢: 30歳 }; let key = プロンプト("ユーザーについて何を知りたいですか?", "名前"); // 変数によるアクセス アラート( ユーザー[キー] ); // ジョン (「名前」を入力した場合)
ドット表記は同様の方法で使用できません。
ユーザー = { にします 名前:「ジョン」、 年齢: 30歳 }; let key = "名前"; alert( user.key ) // 未定義
オブジェクトを作成するときに、オブジェクト リテラルで角括弧を使用できます。それは計算されたプロパティと呼ばれます。
例えば:
let Fruit = Prompt("どの果物を買うべきですか?", "リンゴ"); バッグ = { [fruit]: 5, // プロパティの名前は変数フルーツから取得されます }; アラート(バッグ.アップル); // フルーツ = "リンゴ" の場合は 5
計算プロパティの意味は単純です。 [fruit]
、プロパティ名がfruit
から取得されることを意味します。
したがって、訪問者が"apple"
と入力すると、 bag
{apple: 5}
になります。
基本的に、これは次と同じように機能します。
let Fruit = Prompt("どの果物を買うべきですか?", "リンゴ"); let バッグ = {}; // フルーツ変数からプロパティ名を取得します バッグ[フルーツ] = 5;
…でも見た目は良くなりました。
角括弧内でより複雑な式を使用できます。
果物 = 'リンゴ' とします。 バッグ = { [フルーツ + 'コンピューター']: 5 // Bag.appleComputers = 5 };
角括弧はドット表記よりもはるかに強力です。任意のプロパティ名と変数を許可します。しかし、書くのがさらに面倒でもあります。
したがって、ほとんどの場合、プロパティ名が既知で単純な場合には、ドットが使用されます。さらに複雑なものが必要な場合は、角括弧に切り替えます。
実際のコードでは、既存の変数をプロパティ名の値として使用することがよくあります。
例えば:
function makeUser(名前, 年齢) { 戻る { 名前: 名前、 年齢: 年齢、 // ...その他のプロパティ }; } let user = makeUser("John", 30); アラート(ユーザー名); // ジョン
上の例では、プロパティは変数と同じ名前を持っています。変数からプロパティを作成するユースケースは非常に一般的であるため、それを短くするための特別なプロパティ値の省略表現があります。
name:name
の代わりに、次のようにname
と書くことができます。
function makeUser(名前, 年齢) { 戻る { name, // nameと同じ: name age, // 年齢と同じ: 年齢 // ... }; }
同じオブジェクト内で通常のプロパティと省略表現の両方を使用できます。
ユーザー = { にします name, // name:nameと同じ 年齢: 30歳 };
すでにご存知のとおり、変数には、「for」、「let」、「return」などの言語で予約されている単語のいずれかと同じ名前を付けることはできません。
ただし、オブジェクト プロパティの場合、そのような制限はありません。
// これらのプロパティは問題ありません obj = { にします の場合: 1、 しましょう: 2、 戻り: 3 }; アラート( obj.for + obj.let + obj.return ); // 6
つまり、プロパティ名に制限はありません。任意の文字列または記号 (識別子の特別なタイプ。後で説明します) を使用できます。
他の型は自動的に文字列に変換されます。
たとえば、数値0
プロパティ キーとして使用すると、文字列"0"
になります。
obj = { にします 0: "テスト" // "0": "テスト" と同じ }; // 両方のアラートが同じプロパティにアクセスします (数値 0 は文字列「0」に変換されます) アラート( obj["0"] ); // テスト アラート( obj[0] ); // テスト(同じプロパティ)
__proto__
という名前の特別なプロパティには小さな問題があります。非オブジェクト値に設定することはできません。
obj = {} にします。 obj.__proto__ = 5; // 番号を割り当てる アラート(obj.__proto__); // [object Object] - 値はオブジェクトですが、意図したとおりに動作しませんでした
コードからわかるように、プリミティブ5
への代入は無視されます。
後続の章で__proto__
の特殊な性質について説明し、そのような動作を修正する方法を提案します。
他の多くの言語と比較した場合の JavaScript のオブジェクトの注目すべき機能は、任意のプロパティにアクセスできることです。プロパティが存在しない場合でもエラーは発生しません。
存在しないプロパティを読み取ると、単にundefined
が返されます。したがって、プロパティが存在するかどうかを簡単にテストできます。
ユーザー = {} にします。 alert( user.noSuchProperty === 未定義 ); // true は「そのようなプロパティはない」を意味します
そのための特別な演算子"in"
もあります。
構文は次のとおりです。
オブジェクト内の「キー」
例えば:
let user = { 名前: "ジョン"、年齢: 30 }; alert( user の "年齢" ); // true、user.age が存在します alert( user の "blabla" ); // false、user.blabla は存在しません
in
の左側にはプロパティ名がなければならないことに注意してください。通常、これは引用符で囲まれた文字列です。
引用符を省略した場合、変数にはテスト対象の実際の名前が含まれている必要があることを意味します。例えば:
ユーザー = { 年齢: 30 }; let key = "年齢"; alert( user にキーを入力); // true、プロパティ「age」が存在します
なぜin
演算子が存在するのでしょうか? undefined
と比較するだけでは十分ではないでしょうか?
まあ、ほとんどの場合、 undefined
との比較は正常に機能します。ただし、失敗しても"in"
正しく動作するという特殊なケースがあります。
これは、オブジェクトのプロパティは存在するが、 undefined
格納されている場合です。
obj = { にします テスト: 未定義 }; アラート( obj.test ); // 未定義なので、そのようなプロパティはありませんか? alert( obj の「テスト」); // 確かに、プロパティは存在します。
上記のコードでは、プロパティobj.test
技術的に存在します。したがって、 in
演算子は正しく機能します。
undefined
明示的に割り当てるべきではないため、このような状況は非常にまれに発生します。通常、「不明」または「空」の値にはnull
使用します。したがって、 in
演算子はコード内のエキゾチックなゲストです。
オブジェクトのすべてのキーをたどるには、 for..in
特別な形式のループが存在します。これは、以前に学習したfor(;;)
構造とはまったく異なります。
構文:
for (オブジェクト内のキー) { // オブジェクトのプロパティの各キーの本体を実行します }
たとえば、 user
のすべてのプロパティを出力してみましょう。
ユーザー = { にします 名前:「ジョン」、 年齢:30歳、 isAdmin: true }; for (ユーザーにキーを入力させます) { // キー アラート(キー); // 名前、年齢、isAdmin // キーの値 アラート( ユーザー[キー] ); // ジョン、30 歳、本当です }
すべての「for」構造では、ここでのlet key
のように、ループ内でループ変数を宣言できることに注意してください。
また、ここでkey
の代わりに別の変数名を使用することもできます。たとえば、 "for (let prop in obj)"
も広く使用されています。
オブジェクトは順序付けられていますか?言い換えれば、オブジェクトをループした場合、すべてのプロパティは追加されたのと同じ順序で取得されるのでしょうか?これに頼ってもいいでしょうか?
簡単に言うと、「特別な方法で並べ替える」です。整数プロパティは並べ替えられ、その他は作成順に表示されます。詳細は以下の通りです。
例として、電話コードを持つオブジェクトを考えてみましょう。
コードを許可 = { "49": "ドイツ"、 "41": "スイス"、 "44": "イギリス"、 // ..、 「1」: 「アメリカ」 }; for (コードをコード内にコード化する) { アラート(コード); // 1、41、44、49 }
このオブジェクトは、オプションのリストをユーザーに提案するために使用できます。主にドイツの視聴者向けにサイトを作成している場合は、おそらく49
最初のサイトにしたいと考えます。
しかし、コードを実行すると、まったく異なる状況が表示されます。
米国 (1) が先手
次にスイス (41) など。
電話コードは整数であるため、昇順にソートされます。したがって、 1, 41, 44, 49
がわかります。
整数のプロパティ?あれは何でしょう?
ここでの「整数プロパティ」という用語は、変更せずに整数との間で変換できる文字列を意味します。
したがって、 "49"
整数のプロパティ名です。これは、整数に変換しても、整数に変換しても同じであるためです。ただし、 "+49"
と"1.2"
は次のとおりではありません。
// Number(...) は明示的に数値に変換します // Math.trunc は小数部分を削除する組み込み関数です alert( String(Math.trunc(Number("49"))) ); // "49"、同じ、整数プロパティ alert( String(Math.trunc(Number("+49"))) ); // "49"、同じではありません "+49" ⇒ 整数プロパティではありません alert( String(Math.trunc(Number("1.2"))) ); // "1"、同じではありません "1.2" ⇒ 整数プロパティではありません
…一方、キーが整数でない場合は、次のように作成順にリストされます。
ユーザー = { にします 名前:「ジョン」、 姓:「スミス」 }; ユーザー年齢 = 25; // もう 1 つ追加します // 整数以外のプロパティは作成順にリストされます for (ユーザーに prop を入れます) { アラート( prop ); // 名前、姓、年齢 }
したがって、電話コードの問題を解決するには、コードを非整数にすることで「騙す」ことができます。各コードの前にプラス"+"
記号を追加するだけで十分です。
このような:
コードを許可 = { "+49": "ドイツ", "+41": "スイス"、 "+44": "イギリス", // ..、 「+1」: 「アメリカ」 }; for (コードをコード内にコード化する) { アラート( +コード ); // 49、41、44、1 }
これで、意図したとおりに動作するようになりました。
オブジェクトは、いくつかの特別な機能を備えた連想配列です。
これらはプロパティ (キーと値のペア) を保存します。ここで、
プロパティ キーは文字列または記号 (通常は文字列) である必要があります。
値は任意の型にすることができます。
プロパティにアクセスするには、以下を使用できます。
ドット表記: obj.property
。
角かっこ表記obj["property"]
。角括弧を使用すると、 obj[varWithKey]
のように変数からキーを取得できます。
追加の演算子:
プロパティを削除するには、 delete obj.prop
。
指定されたキーを持つプロパティが存在するかどうかを確認するには: "key" in obj
。
オブジェクトを反復処理するには: for (let key in obj)
ループ。
この章で学習したものは、「プレーン オブジェクト」、または単にObject
と呼ばれます。
JavaScript には他にも多くの種類のオブジェクトがあります。
順序付けられたデータコレクションを保存するArray
、
日付と時刻に関する情報を保存するDate
、
エラーに関する情報を保存するためのError
。
…等々。
それらにはそれぞれの特別な機能がありますが、それについては後ほど説明します。時々、「配列型」や「日付型」などと言われることがありますが、正式にはこれらは独自の型ではなく、単一の「オブジェクト」データ型に属します。そして彼らはそれをさまざまな方法で拡張します。
JavaScript のオブジェクトは非常に強力です。ここでは、非常に大きなトピックの表面をなぞっただけです。オブジェクトを詳しく扱い、チュートリアルの今後の部分でオブジェクトについてさらに学習していきます。
重要度: 5
アクションごとに 1 行でコードを記述します。
空のオブジェクトuser
を作成します。
プロパティname
値John
とともに追加します。
プロパティsurname
値Smith
で追加します。
name
の値をPete
に変更します。
オブジェクトからプロパティname
を削除します。
ユーザー = {} にします。 user.name = "ジョン"; user.surname = "スミス"; user.name = "ピート"; ユーザー名を削除します。
重要度: 5
オブジェクトにプロパティがない場合はtrue
、そうでない場合はfalse
を返す関数isEmpty(obj)
を作成します。
次のように動作するはずです:
スケジュール = {} にします。 アラート( isEmpty(スケジュール) ); // 真実 スケジュール["8:30"] = "起きます"; アラート( isEmpty(スケジュール) ); // 間違い
テストを含むサンドボックスを開きます。
オブジェクトをループし、少なくとも 1 つのプロパティがある場合はすぐにreturn false
。
関数 isEmpty(obj) { for (obj にキーを入れます) { // ループが開始されている場合、プロパティがあります false を返します。 } true を返します。 }
サンドボックス内のテストを含むソリューションを開きます。
重要度: 5
私たちのチームの給与を保存するオブジェクトがあります。
給与 = { とします ジョン: 100、 アン: 160、 ピート: 130 }
すべての給与を合計し、変数sum
に格納するコードを作成します。上の例では390
である必要があります。
salaries
が空の場合、結果は0
でなければなりません。
給与 = { とします ジョン: 100、 アン: 160、 ピート: 130 }; 合計 = 0 とします。 for (給与を入力させます) { 合計 += 給与[キー]; } アラート(合計); // 390
重要性: 3
obj
のすべての数値プロパティ値を2
で乗算する関数multiplyNumeric(obj)
を作成します。
例えば:
// 呼び出しの前に メニュー = { にしましょう 幅: 200、 高さ: 300、 タイトル:「私のメニュー」 }; multiplyNumeric(メニュー); // 呼び出し後 メニュー = { 幅: 400、 高さ: 600、 タイトル:「私のメニュー」 };
multiplyNumeric
何も返す必要がないことに注意してください。オブジェクトをその場で変更する必要があります。
PS ここで数値を確認するにはtypeof
を使用します。
テストを含むサンドボックスを開きます。
関数 multiplyNumeric(obj) { for (obj にキーを入れます) { if (obj[キーの種類] == '数値') { obj[キー] *= 2; } } }
サンドボックス内のテストを含むソリューションを開きます。