序文ES6 より前では、JavaScript のオブジェクト リテラル (オブジェクト初期化子とも呼ばれます) は非常に基本的なものでした。次の 2 種類のプロパティを定義できます。
var myObject = { myString: '値 1', myNumber() を取得 { this._myNumber を返します。 }, myNumber(値)を設定する{ this._myNumber = Number(値); }, }; myObject.myString; // => '値 1' myObject.myNumber = '15'; myObject.myNumber; // => 15 js はプロトタイプベースの言語なので、すべてがオブジェクトです。 オブジェクトの作成、構成、プロトタイプへのアクセスに関しては、構築を容易にする言語を提供する必要があります。 オブジェクトを定義し、そのプロトタイプを設定することは一般的なタスクです。最善の方法は、オブジェクトリテラルの単一のステートメントでプロトタイプを直接設定することです。 残念ながら、リテラルの制限により、これを実現するための簡単な解決策は存在しません。プロトタイプを設定するには、オブジェクトリテラルと組み合わせて object.create() を使用する必要があります。 var myProto = { プロパティが存在する: 関数(名前) { これで名前を返します。 } }; var myNumbers = Object.create(myProto); myNumbers['arrat'] = [1, 6, 7]; myNumbers.propertyExists('array'); // => true myNumbers.propertyExists('collection'); // => false この解決策は柔軟性が十分ではないと思います。 JS はプロトタイプベースですが、プロトタイプを使用してオブジェクトを作成するのはなぜ面倒なのでしょうか? 幸いなことに、JS も徐々に改善しています。 JS の多くの厄介な問題は段階的に解決されます。 この記事では、ES6 が上記の問題をどのように解決し、追加機能によってオブジェクトリテラルを改善するかを説明します。
1. オブジェクト構築にプロトタイプを設定するご存知のとおり、既存のオブジェクトのプロトタイプにアクセスする 1 つの方法は、ゲッター プロパティ __proto__ を使用することです。 var myObject = { 名前: 'Hello World!', }; myObject.__proto__; // => {} myObject.__proto__.isPrototypeOf(myObject); // => true myObject.__proto__ は、myObject のプロトタイプ オブジェクトを返します。 object.__proto__ をゲッター/セッターとして使用することは推奨されないことに注意してください。代替アプローチとしては、Object.getPrototypeOf() と Object.setPrototypeOf() の使用を検討する必要があります。 ES6 では、プロパティ名として __proto__ を使用し、{__proto__: protoObject} でプロトタイプを設定できます。 次に、__proto__ プロパティを使用してオブジェクトを初期化し、上記のコードを最適化します。 var myProto = { プロパティが存在する: 関数(名前) { これで名前を返します。 }, }; var myNumbers = { __proto__: myProto、 配列: [1, 6, 7], }; myNumbers.propertyExists('array'); // => true myNumbers.propertyExists('collection'); // => false myNumbers オブジェクトは、特別なプロパティ名 proto とプロトタイプ myProto を使用して作成されます。今回は、上記の object.create() のような追加の関数を必要とせず、単一のステートメントで作成します。 ご覧のとおり、__proto__ を使用したコーディングはシンプルで、私は常にシンプルで明確なソリューションを好みます。 話題から外れた話をしましょう。 シンプルで柔軟なソリューションにこれほど多くの作業と設計が必要になるのは奇妙だと思います。解決策が単純なら、設計も簡単だと思われるかもしれません。しかし、逆もまた真なりです。
複雑すぎる、または使いにくいと思われる場合は、さらに改良する必要があるかもしれません。 1.1 __proto__ の使用における特殊なケース__proto__ は単純に見えますが、知っておくべき特殊なケースがいくつかあります。 オブジェクトリテラルでは __proto__ を 1 回だけ使用できます。そうでない場合、JS はエラーを報告します。 varオブジェクト = { __proto__: { toString: 関数() { '[オブジェクト番号]' を返す } }, 数字: [1, 5, 89], __proto__: { toString: 関数() { '[オブジェクト ArrayOfNumbers]' を返します } } }; 上記の例では、オブジェクトリテラル内で __proto__ プロパティを 2 回使用していますが、これは許可されていません。この場合、エラーがスローされます: SyntaxError: オブジェクトリテラルでは重複する __proto__ フィールドは許可されません。 JS では、__proto__ プロパティの値として使用できるのはオブジェクトまたは null のみと制限されています。 プリミティブ型 (文字列、数値、ブール値) または undefined の使用は無視され、オブジェクトのプロトタイプは変更されません。 var obj未定義 = { __proto__: 未定義、 }; Object.getPrototypeOf(objUndefined); // => {} var オブジェクト番号 = { __proto__: 15, }; Object.getPrototypeOf(objNumber); // => {} オブジェクトリテラルは、undefined と数値 15 を使用して __proto__ 値を設定します。 プロトタイプとして許可されるのはオブジェクトまたは null のみであるため、__proto__ 値は無視されますが、objUndefined と objNumber にはデフォルトのプロトタイプ (プレーンな JS オブジェクト {}) が保持されます。 もちろん、プリミティブ型を使用してオブジェクトのプロトタイプを設定しようとするのも奇妙です。 また、オブジェクトリテラルに '__proto__' { ['__proto__']: protoObj } と評価される文字列がある場合にも注意してください。 この方法で作成されたプロパティはオブジェクトのプロトタイプを変更せず、単にキー '__proto__' を持つ所有プロパティを作成します。 2. 簡略化されたメソッド定義関数キーワードと : コロンを省略して、より短い構文を使用してオブジェクト リテラルでメソッドを宣言できます。 これは、短縮メソッド定義と呼ばれます。 次に、ショートカット メソッドを使用していくつかのメソッドを定義してみましょう。 var コレクション = { アイテム: [], 追加(アイテム) { this.items.push(アイテム); }, get(インデックス) { this.items[index]を返します。 }, }; コレクション.add(15); コレクション.add(3); コレクション.get(0); // => 15 大きな利点は、この方法で宣言されたメソッドは関数として名前が付けられ、デバッグに便利であることです。 上記の例から collection.add.name を実行すると、関数名「add」が返されます。 3. スーパーの使用JS の興味深い改善点は、プロトタイプ チェーンから継承されたプロパティにアクセスする方法として super キーワードを使用できることです。 次の例を見てください。 var calc = { 数値: null、 要素の合計(){ this.numbers.reduce(function(a, b) { を返す a + b を返します。 }); }, }; var 数字 = { __proto__: calc、 数字: [4, 6, 7], 要素の合計(){ this.numbers == null || this.numbers.length === 0 の場合 { 0を返します。 } super.sumElements() を返します。 }, }; numbers.sumElements(); // => 17 calc は、numbers オブジェクトのプロトタイプです。 数値の sumElements メソッドでは、 super キーワードを使用してプロトタイプからメソッドにアクセスできます: super.sumElements() 結局のところ、super はオブジェクトのプロトタイプ チェーンから継承されたプロパティにアクセスするためのショートカットです。 前の例では、calc.sumElements() を直接実行してプロトタイプを呼び出そうとすると、エラーが発生します。 ただし、super.sumElements() はオブジェクトのプロトタイプ チェーンにアクセスするため、正しく呼び出すことができます。また、プロトタイプの sumElements() メソッドが this.numbers を使用して配列に正しくアクセスしていることを確認します。 super が存在すると、継承されたプロパティが使用されることが明確になります。 3.1 スーパーの使用制限super は、オブジェクトリテラル内の短縮メソッド定義内でのみ使用できます。 通常のメソッド宣言 { name: function(){} } からアクセスしようとすると、JS はエラーをスローします。 var calc = { 数値: null、 要素の合計(){ this.numbers.reduce(function(a, b) { を返す a + b を返します。 }); }, }; var 数字 = { __proto__: calc、 数字: [4, 6, 7], 要素の合計: 関数() { this.numbers == null || this.numbers.length === 0 の場合 { 0を返します。 } super.sumElements() を返します。 }, }; // SyntaxError がスローされます: 'super' キーワードは予期されていません 数値.sumElements(); メソッド sumElements は、プロパティとして定義されます: sumElements: function() {…}。 super は短縮メソッド内でのみ使用できるため、このコンテキストで呼び出すと、SyntaxError: 'super' keyword expected here がスローされます。 この制限は、オブジェクトリテラルの宣言方法に大きな影響を与えません。 通常は、構文が短いため、短縮メソッド定義を使用する方が適切です。 4. 計算されたプロパティ名ES6 より前では、オブジェクトはリテラル値 (通常は静的文字列) を使用して初期化されていました。 計算された名前を持つプロパティを作成するには、プロパティ アクセサーを使用する必要があります。 関数プレフィックス(prefStr, 名前) { prefStr + '_' + 名前を返します。 } var オブジェクト = {}; オブジェクト[プレフィックス('number', 'pi')] = 3.14; オブジェクト[プレフィックス('bool', 'false')] = false; オブジェクト; // => { number_pi: 3.14, bool_false: false } もちろん、プロパティを定義するこの方法は満足のいくものです。 次に、ショートカット メソッドを使用して上記の例を変更します。 関数プレフィックス(prefStr, 名前) { prefStr + '_' + 名前を返します。 } varオブジェクト = { [接頭辞('数値', '円周率')]: 3.14, [プレフィックス('bool', 'false')]: 偽、 }; オブジェクト; // => { number_pi: 3.14, bool_false: false } [prefix('number', 'pi')] は、prefix('number', 'pi') 式 (つまり 'number_pi') を評価して属性名を設定します。 同様に、[prefix('bool', 'false')] は 2 番目の属性名を 'bool_false' に設定します。 4.1 属性名としてのシンボルシンボルは計算されたプロパティ名としても使用できます。 必ず角括弧で囲んでください: {[Symbol('name')]:'Prop value'} たとえば、特別なプロパティ Symbol.iterator を使用して、オブジェクト自体のプロパティ名を反復処理します。 次の例に示すように: varオブジェクト = { 番号1: 14, 番号2: 15, 文字列1: 'こんにちは', 文字列2: '世界', [シンボル.イテレータ]: 関数 *() { var 所有 = Object.getOwnPropertyNames(これ), プロップ; while(prop = own.pop()) { 利回りプロップ; } } } [...オブジェクト]; // => ['数値1', '数値2', '文字列1', '文字列2'] [Symbol.iterator]: function *() { } オブジェクト自身のプロパティを反復処理するために使用されるプロパティを定義します。 スプレッド演算子 [...] オブジェクトはイテレータを受け取り、独自のプロパティのリストを返します。 5. 残りと拡張プロパティ残存プロパティを使用すると、オブジェクトが割り当てられて破棄された後に残っているプロパティをオブジェクトから収集できます。 次の例では、オブジェクトを分解した後、残りのプロパティを収集します。 varオブジェクト = { プロップA: 1, プロップB: 2, プロップC: 3, }; propA、...restObject をオブジェクトとします。 propA; // => 1 restObject; // => { propB: 2, propC: 3 } スプレッド プロパティを使用すると、ソース オブジェクトの独自のプロパティをオブジェクト リテラルにコピーできます。 この例では、オブジェクト リテラルはソース オブジェクトからオブジェクトに追加のプロパティを収集します。 var ソース = { プロップB: 2, プロップC: 3, }; varオブジェクト = { プロップA: 1, ...ソース、 }; オブジェクト; // => { propA: 1, propB: 2, propC: 3 } 6. まとめオブジェクトリテラルという比較的小さな構造でさえ、ES6 では大幅に改善されています。 オブジェクトのプロトタイプは、__proto__ プロパティ名を使用して初期化子から直接設定できます。 これは Object.create() を使用するよりも簡単です。 __proto__ は ES6 標準の Annex B の一部であり、その使用は推奨されないことに注意してください。 このアドオンの実装はブラウザでは必須ですが、他の環境ではオプションです。この機能は、NodeJS 4、5、6 でサポートされています。 メソッド宣言フォームが短くなったため、関数キーワードを入力する必要がなくなりました。 簡略化された方法では、 super キーワードを使用できます。これにより、オブジェクトのプロトタイプ チェーン内の継承されたプロパティに簡単にアクセスできます。 プロパティ名が実行時に計算される場合は、計算されたプロパティ名 [式] を使用してオブジェクトを初期化できるようになりました。 以上がJSにおけるオブジェクトリテラルの詳しい説明です。JSオブジェクトリテラルの詳細については、123WORDPRESS.COMの他の関連記事もご覧ください。 以下もご興味があるかもしれません:
|
<<: Linux クラウド サーバーに新しいディスクをマウントする方法
>>: MySQL の日付関数と日付変換およびフォーマット関数
インデックスの簡単な紹介は次のとおりです。インデックスを追加する目的は、データベース クエリのパフォ...
SSH は Secure Shell の略で、安全な伝送プロトコルです。Ubuntu クライアントは...
<br />矛盾が生じます。私たちのような小さな工房では、デザインとレイアウトは基本的に...
私のおすすめ複数のIEバージョンの共存のためのソリューション以前に IE6、IE7、IE8 の共存に...
目次1. Lvsの紹介2. Lvs負荷分散モード2.1 NAT 2.2 ターン2.3 DRモード3....
目次安定スロットリング要約する安定自動ドアは人を感知してドアを開け、5 秒間のカウントダウンを開始し...
目次1. 目的2. 環境整備1. 基本情報2. データベース環境の準備3. データベースを構築し、サ...
目次親コンポーネントと子コンポーネント間でパラメータを渡すルーティングパラメータステータスの改善コン...
ボタンをクリックしてテキストを入力ボックスに変換し、保存をクリックしてテキスト実装コードに変換します...
この記事では、Linux MySQL 8.0.18のインストールと設定のグラフィックチュートリアルを...
スタイルシートCSS (カスケーディング スタイル シート) は、HTML Web ページを美しくす...
1. Dockerをインストールするyum -y install docker-ioインストールが完...
1. Apache Benchの紹介ApacheBench は、Apache サーバーに付属する W...
目次序文1. カスタムフォーカスコマンド1. 方法1 2. 方法2 3. 方法3 2. 入力ボックス...
この記事は主に、Vue のレスポンシブ ソース コードを理解していない、または触れたことがない人向け...