この出版物は、Zell Liewによる記事「よく使用されるES6機能の紹介」の翻訳の第2部 です 。 最初の部分の翻訳は こちらです。
再編
構造化は、配列とオブジェクトから値を抽出する便利な方法です。 配列とオブジェクトの構造化にはわずかな違いがあるため、それらを個別に検討します。
オブジェクトの再構築
次のオブジェクトがあるとします。
const Zell = { firstName: 'Zell', lastName: 'Liew' }
Zell
からfirstName
とlastName
を取得するには、2つの変数を作成し、次のように各変数に値を割り当てる必要があります。
let firstName = Zell.firstName; // Zell let lastName = Zell.lastName; // Liew
構造化により、これらの変数の作成と割り当ては1行のコードで実行されます。 以下はオブジェクトの破壊の例です。
let { firstName, lastName } = Zell; console.log(firstName); // Zell console.log(lastName); // Liew
変数宣言に中括弧が追加されると、これらの変数を作成し、 Zell.firstName
をfirstName
に、 Zell.lastName
をlastName
割り当てる命令が作成されます。
「フード」の下で何が起こるかを説明しましょう。
// , : let { firstName, lastName } = Zell; // , ES6 : let firstName = Zell.firstName; let lastName = Zell.lastName;
これで、変数名がすでに使用let
場合、同じ変数を再度宣言することはできません(特にlet
またはconst
を使用する場合)。
次のコードは機能しません。
let name = 'Zell Liew'; let course = { name: 'JS Fundamentals for Frontend Developers' // ... } let { name } = course; // Uncaught SyntaxError:
このような状況では、コロンの再構築と同時に変数の名前を変更できます。
以下の例では、変数courseName
が作成され、 courseName
がcourse.name
割り当てられcourse.name
。
let { name: courseName } = course; console.log(courseName); // JS Fundamentals for Frontend Developers // , ES6 : let courseName = course.name;
オブジェクトにない変数を構造化undefined
すると、 undefined
が返されることに注意してください。
let course = { name: 'JS Fundamentals for Frontend Developers' } let { package } = course; console.log(package); // undefined
デフォルト設定を覚えていますか? 破壊された変数のデフォルトのパラメーターを記述することもできます。 構文は、関数宣言の構文に似ています。
let course = { name: 'JS Fundamentals for Frontend Developers' } let { package = 'full course' } = course; console.log(package); // full course
デフォルトのパラメーターを指定して、変数の名前を変更することもできます。 2つの構文を組み合わせて作成する必要がありますが、最初は普通ではありませんが、慣れることができます。
let course = { name: 'JS Fundamentals for Frontend Developers' } let { package: packageName = 'full course' } = course; console.log(packageName); // full course
これは、オブジェクトの破壊に関するすべてです。 次に、配列の分解を検討します。
配列の破壊
配列とオブジェクトの分解も同様です。 配列を操作する場合、中括弧の代わりに角括弧が使用されます。
配列を再構築する場合:
- 1番目の変数-配列の最初の要素
- 2番目の変数-配列の2番目の要素
- など
let [one, two] = [1, 2, 3, 4, 5]; console.log(one); // 1 console.log(two); // 2
分解中に変数の数が配列のサイズを超える場合、追加の変数はundefined
ます。
let [one, two, three] = [1, 2]; console.log(one); // 1 console.log(two); // 2 console.log(three); // undefined
配列を分解する場合、必要な変数のみが抽出されることがよくあります。 残りを取得するには、restステートメントを次のように使用します。
let scores = ['98', '95', '93', '90', '87', '85']; let [first, second, third, ...rest] = scores; console.log(first); // 98 console.log(second); // 95 console.log(third); // 93 console.log(rest); // [90, 87, 85]
残りのステートメントについては、次のパートで詳しく説明します。 ここで、配列の破壊を使用した変数の順列を見てみましょう。
配列の破壊を使用した変数の順列
2つの変数a
とb
a
とします。
let a = 2; let b = 3;
これらの変数を再配置して、 b
が3に等しくなり、 b
が2に等しくなるようにする必要があります。ES5では、一時的な3番目の変数を使用してこの問題を解決します。
let a = 2; let b = 3; let temp; // temp = a; // temp 2 a = b; // a 3 b = temp; // b 2
このようなコードは、3番目の変数を含めることで、あいまいでわかりにくいロジックにもかかわらず機能します。
ES6の配列の構造化により、これは次の方法で解決されます。
let a = 2; let b = 3; // [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 2
変数を並べ替えるこの方法は、前の方法よりもはるかに簡単です。
次に、関数内の配列とオブジェクトの分解を検討します。
関数を宣言する際の配列とオブジェクトの構造化
構造化は、関数を宣言する場合でも、文字通りどこでも使用できます。
値の配列を受け取り、上位3つの値を持つオブジェクトを返す関数があるとします。 このような関数は、配列の破壊中に起こることと類似しています。
function topThree (scores) { let [first, second, third] = scores; return { first: first, second: second, third: third } }
このような関数を記述する別の方法は、関数を宣言するときにscores
を再構築することです。 この場合、1行少ないコードを記述する必要があります。 また、配列が関数に渡されることを覚えておく必要があります。
function topThree ([first, second, third]) { return { first: first, second: second, third: third } }
関数を宣言するときにデフォルトのパラメーターと再構築を組み合わせることができる場合、以下のコードの結果はどうなりますか?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew' } = {}) { console.log(firstName + ' ' + lastName); }
最初に 、関数は単一のオブジェクト引数を取ることに注意してください。 このオブジェクトはオプションであり、デフォルトは{}
です。
次に 、渡されたオブジェクトから変数firstName
およびlastName
を破棄しようとします。 そのようなプロパティが見つかった場合、それらが使用されます。
その結果、オブジェクトにfirstName
またはlastName
定義されlastName
いない( undefined
)場合、それぞれ値Zell
およびLiew
が割り当てられます。
したがって、このような関数は次の結果を出力します。
sayMyName(); // Zell Liew sayMyName({firstName: 'Zell'}); // Zell Liew sayMyName({firstName: 'Vincy', lastName: 'Zhang'}); // Vincy Zhang
次に、休息と広がりを考慮します。
レストパラメーターとスプレッド演算子
Restパラメーターとスプレッド演算子は似ています。なぜなら、 両方とも3つのドットで示されます。 ただし、使用時のパフォーマンスは異なります。 このため、これらは異なる名前が付けられており、個別に考慮されます。
レストパラメーター
残りの自由な解釈では、パラメーターは残りのデータを取得して配列にラップすることを示します。 詳細には、コンマで区切られた引数のリストが配列に変換されます。
動作中のrestパラメーターについて理解しましょう。 引数を要約するadd
関数があるとします:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 55
ES5では、未知の数の変数を受け入れる関数を扱うたびにarguments
変数に依存します。 arguments
変数は、配列のようなSymbol
です。
function sum () { console.log(arguments); } sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
![](https://habrastorage.org/webt/wy/b9/ne/wyb9nefj494x8dtuc3skoyyns0y.png)
Arguments
- Symbol
(配列ではない)
この引数の合計を計算する1つの方法は、 Array.prototype.slice.call(arguments
)を使用して配列に変換し、 forEach
やreduce
などの配列メソッドを使用して各要素をループするreduce
です。
forEach
自分で実装できると確信しているので、 reduce
例を以下に示しreduce
。
// ES5 function sum () { let argsArray = Array.prototype.slice.call(arguments); return argsArray.reduce(function(sum, current) { return sum + current; }, 0) }
ES6では、restパラメーターを使用して、コンマ区切りの引数を配列に直接変換できます。
// ES6 const sum = (...args) => args.reduce((sum, current) => sum + current, 0); // ES6 function sum (...args) { return args.reduce((sum, current) => sum + current, 0); }
Restパラメーターについては、以前に破壊に関するセクションで簡単に説明しました。 次に、上位3つの値が配列から破棄されました。
let scores = ['98', '95', '93', '90', '87', '85']; let [first, second, third] = scores; console.log(first); // 98 console.log(second); // 95 console.log(third); // 93
残りのデータを取得する必要がある場合は、restパラメーターを参照します。
let scores = ['98', '95', '93', '90', '87', '85']; let [first, second, third, ...restOfScores] = scores; console.log(restOfScores); // [90, 97, 95]
混乱を招く場合は、restパラメーターがデータを配列に変換し、関数のパラメーター内および配列の破壊中に表示されることに注意してください。
次に、スプレッド演算子について考えます。
スプレッドステートメント
Spreadステートメントは、restパラメーターの反対に作用します。 自由な解釈では、演算子は配列を取り、引数のコンマ区切りリストに展開します。
let array = ['one', 'two', 'three']; // console.log(...array); // one two three console.log('one', 'two', 'three'); // one two three
Spread演算子は、読みやすく理解しやすい方法で配列を連結するためによく使用されます。
次の配列を結合するとします。
let array1 = ['one', 'two']; let array2 = ['three', 'four']; let array3 = ['five', 'six'];
ES5はArray.concat
メソッドを使用して配列を連結します。 複数の配列を結合するために、チェーンは次のように構築されます。
// ES5 let combinedArray = array1.concat(array2).concat(array3); console.log(combinedArray) // ['one', 'two', 'three', 'four', 'five', 'six'];
ES6スプレッドでは、演算子を使用すると、読みやすい方法で配列を新しい配列に結合できます。
// ES6 let combinedArray = [...array1, ...array2, ...array3]; console.log(combinedArray); // ['one', 'two', 'three', 'four', 'five', 'six']
Spread演算子を使用して、配列を変更せずに配列から要素を削除することもできます。 この方法はReduxで一般的です。 Dan Abramovのビデオを見て、その仕組みを理解することをお勧めします。
拡張オブジェクトリテラル
ES6の拡張オブジェクトリテラルは、3つの機能強化をもたらします。 これらには以下が含まれます。
- プロパティ値の略語、
- メソッドの略語
- 計算されたプロパティ名を使用する機能。
それぞれについて考えてみましょう。
プロパティ値の略語
オブジェクトのプロパティの名前と一致する名前の変数をオブジェクトのプロパティに書き込むことがあることに気づきましたか? これを次の例に示します。
const fullName = 'Zell Liew'; const Zell = { fullName: fullName }
そのような状況では、より短いコードを書きたいですか?
ES6は、プロパティ値の略語でオブジェクトを展開します。つまり、変数名がプロパティの名前と一致する場合にのみ変数を書き込むことができます。
次のようになります。
const fullName = 'Zell Liew'; // ES6 const Zell = { fullName } // , ES6: const Zell = { fullName: fullName }
メソッドの略語
メソッドは、オブジェクトのプロパティに関連付けられた関数です。 以下にメソッドの例を示します。
const anObject = { aMethod: function () { console.log("I'm a method!~~")} }
ES6のメソッドのショートカットは、メソッド宣言から: function
を削除しても操作が中断されないことです。
const anObject = { // ES6 aShorthandMethod (arg1, arg2) {}, // ES5 aLonghandMethod: function (arg1, arg2) {}, }
この改善により、オブジェクトはすでにメソッドの省略形を受け取っているため、オブジェクトを宣言するときに矢印関数を使用することはお勧めしません。 これは、このコンテキストを壊します(これがなぜ起こるのか覚えていない場合は、矢印関数のセクションに戻ります)。
const dontDoThis = { // : arrowFunction: () => {} }
それでは、オブジェクトの最後の改善に移りましょう。
計算されたオブジェクトプロパティ名
オブジェクトを作成するときに動的プロパティ名が必要になる場合があります。 以前は、オブジェクトを作成してから、次の方法でプロパティを追加する必要がありました。
// ES5 const newPropertyName = 'smile'; // const anObject = { aProperty: 'a value' } // anObject[newPropertyName] = ':D'; // anObject['bigger ' + newPropertyName] = 'XD'; // // { // aProperty: 'a value', // 'bigger smile': 'XD' // smile: ':D', // }
ES6では、次のような「回避策」は必要ありません。 オブジェクトの作成時に動的プロパティ名を直接割り当てることができます。 同時に、動的プロパティを角括弧で囲むことが重要です。
const newPropertyName = 'smile'; // ES6 const anObject = { aProperty: 'a value', // [newPropertyName]: ':D', ['bigger ' + newPropertyName]: 'XD', } // // { // aProperty: 'a value', // 'bigger smile': 'XD' // smile: ':D', // }
これが拡張オブジェクトリテラルのすべてです。 次に、別の便利な機能、パターン文字列を検討します。
パターン文字列
JavaScriptで文字列を操作することは非常に難しいプロセスです。 デフォルトのパラメーターに関するセクションでannouncePlayer関数を作成するときにこれに遭遇しました。 次のコードは、追加によって結合される空の行を持つスペースを作成します。
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName); }
ES6では、この問題はテンプレートリテラルによって解決されています(以前は仕様ではテンプレート文字列と呼ばれていました)。
テンプレートリテラルを作成するには、文字列を逆アポストロフィで囲む必要があります。 逆アポストロフィの内側では、特別なポインター${}
、そこでJavaScriptコードを記述できます。
次に、実際の動作の例を示します。
const firstName = 'Zell'; const lastName = 'Liew'; const teamName = 'unaffiliated'; const theString = `${firstName} ${lastName}, ${teamName}`; console.log(theString); // Zell Liew, unaffiliated
したがって、テンプレートリテラルを使用してさまざまな組み合わせを構成することが可能になりました。これは、テンプレートエンジンの使用に似ています。
テンプレートリテラルの最も便利な機能は、複数行の文字列を作成できることです。 以下に例を示します。
const multi = `One upon a time, In a land far far away, there lived a witich, who could change night into day`;
![](https://habrastorage.org/webt/v3/ge/_k/v3ge_k550huiwytmxnlqzc9kheg.png)
このような行は、JavaScriptコードでHTML要素を作成するために使用できます(これはHTML要素を作成する最良の方法ではありませんが、1つずつ個別に作成するよりも優れています)。
const container = document.createElement('div'); const aListOfItems = `<ul> <li>Point number one</li> <li>Point number two</li> <li>Point number three</li> <li>Point number four</li> </ul>`; container.innerHTML = aListOfItems; document.body.append(container);
テンプレートリテラルのもう1つの機能はタグです。 タグは、テンプレートリテラルを操作して任意の文字列を置換できる関数です。
以下に例を示します。
const animal = 'lamb'; // const tagFunction = () => { // } // tagFunction const string = tagFunction `Mary had a little ${animal}`;
正直に言って、テンプレートタグが印象的であるという事実にもかかわらず、私はまだアプリケーションの状況がありませんでした。 それらをさらに詳しく調べるには、MDNの資料を読むことをお勧めします。
おわりに
これらはすべて、私が定期的に使用するES6の機能です。 他の人が何を書いているのかを理解するために、少し時間をかけて勉強する価値があることは間違いありません。