ES6の一般的に使用される機能の紹介。 パート1

この出版物は、Zell Liewによる記事「一般的に使用されるES6機能の紹介」の翻訳版 です 翻訳は2つの部分に分かれています。 第2部の翻訳は こちらです。







JavaScriptはここ数年で大きく進化しました。 2017年に言語を学習していて、まだECMAScript 6(ES6)に触れていない場合は、簡単に読み書きできる方法がありません。







あなたがまだ言語の専門家でなくても心配しないでください。 ES6で追加された「ボーナス」を活用するために、完全に知る必要はありません。 この記事では、開発者として毎日使用しているES6の8つの機能を紹介します。これにより、新しい構文に簡単に没頭できます。









翻訳者のメモ:この記事には7つの機能があります(「約束」については別の記事で説明します)。







ES6機能リスト



まず、ES6は巨大なJavaScriptアップデートです。 以下に機能の長いリストを示します (Luke Hobanに感謝します)。興味がある場合は、どのような革新が登場しましたか。









ES6のこのような多数の機能のリストを恐れないでください。 一度にすべてを知る必要はありません。 次に、毎日適用する8つの機能を共有します。 これらには以下が含まれます。







  1. let + const
  2. 矢印関数
  3. デフォルトのパラメーター
  4. 再編
  5. レストパラメーターとスプレッド演算子
  6. 拡張オブジェクトリテラル
  7. パターン文字列
  8. 約束


ところで、ブラウザはES6を非常によくサポートしています。 ブラウザの最新バージョン(Edge、FF、Chrome、Safariの最新バージョン)のコードを記述すると、ほとんどすべての機能がネイティブで提供されます







ES6でコードを作成するには、Webpackのようなツールは必要ありません。 ブラウザがサポートされていない場合、コミュニティが作成したポリフィルをいつでも参照できます。 グーグルに十分。







それでは、最初の機能に取りかかりましょう。







Letとconst



ES5(「古い」JavaScript)では、 var



キーワードを使用して変数を宣言するのが慣習でした。 ES6では、この単語は、開発を容易にする2つの強力なキーワードであるlet



およびconst



置き換えることができます。







まず、 let



var



違いに注意して、 let



const



const



優れている理由を理解してlet









Let vs var



まず、使い慣れたvar



検討します。







最初に、 var



キーワードを使用して変数を宣言できます。 宣言が発生すると、変数は現在のスコープのどこでも使用できます。







 var me = 'Zell' ; console.log(me); // Zell
      
      





上記の例では、グローバル変数me



宣言されています。 この変数は関数でも使用できます。 たとえば、次のように:







 var me = 'Zell'; function sayMe () { console.log(me); } sayMe(); // Zell
      
      





ただし、その逆は当てはまりません。 関数で変数が宣言されている場合、関数の外部で変数を使用することはできません。







 function sayMe() { var me = 'Zell'; console.log(me); } sayMe(); // Zell console.log(me); // Uncaught ReferenceError: me is not defined
      
      





したがって、 var



スコープは「機能的」であると言えます。 これは、変数が関数内でvar



で宣言されると、関数内にのみ存在することを意味します。







関数の外部で変数が作成された場合、その変数は外側のスコープに存在します。







 var me = 'Zell'; //    function sayMe () { var me = 'Sleepy head'; //    console.log(me); } sayMe(); // Sleepy head console.log(me); // Zell
      
      





一方、には、 「ブロック」スコープがあります。 これは、letを使用して変数が宣言されると、その変数はブロック内にのみ存在することを意味します。







待ってください。しかし、「ブロック」とはどういう意味ですか?







JavaScriptのブロックは、中括弧のペアの中にあります。 ブロックの例を次に示します。







 { //   } if (true) { //   } while (true) { //   } function () { //   }
      
      





「ブロック」と「機能的に」宣言された変数の違いは非常に大きいです。 将来変数を「機能的に」宣言すると、この変数の値を誤って書き換えることがあります。 以下に例を示します。







 var me = 'Zell'; if (true) { var me = 'Sleepy head'; } console.log(me); // 'Sleepy head'
      
      





この例は、 if



ブロック内のコードを実行した後、 me



の値が'Sleepy head'



になることを示しています。 そのような例は、ほとんどの場合、問題を引き起こしません。 同じ名前の変数が宣言されることはほとんどありません。







ただし、 for



ループを介してvar



を操作している人は、変数の宣言方法が原因で奇妙な状況に陥ることがあります。 変数i



4回表示し、 setTimeout



関数を使用してi



を出力する次のコードを想像してください。







 for (var i = 1; i < 5; i++) { console.log(i); setTimeout(function () { console.log(i); }, 1000) };
      
      





このコードの実行時にどのような結果が期待できますか? 以下は実際に起こることです:













i は、タイマー機能で値「5」とともに4回表示されます。







タイマー内で値「5」を4回取得する方法 これは、 var



が変数を「機能的に」定義し、タイマーの実行が開始される前でもi



の値が「4」になるためです。







後で実行されるsetTimeout



内で正しいi



値を取得するには、別の関数、たとえばlogLater



を作成して、 setTimeout



の開始前にfor



ループでi



値が変更されないようにするfor



ます。







 function logLater (i) { setTimeout(function () { console.log(i); }); } for (var i = 1; i < 5; i++) { console.log(i); logLater(i); };
      
      











iは 1、2、3、4として正しく表示されます







ところで、これはクロージャーと呼ばれます。







幸いなことに、 for



ループの例に示す「機能的に」定義されたスコープの「奇妙さ」は、 let



では発生しません。 追加の機能を追加せずに動作するように、同じタイマーの例を書き換えることができます。







 for (let i = 1; i < 5; i++) { console.log(i); setTimeout(function () { console.log(i); }, 1000); };
      
      











iは 1、2、3、4として正しく表示されます







ご覧のように、「ブロック」宣言された変数は、「機能的に」宣言された変数の欠点を回避し、開発を大幅に簡素化します。 簡単にするために、今後JavaScriptで変数を宣言する必要があるたびに、 var



代わりにlet



を使用することをお勧めします。







let



機能を理解したら、 let



const



違いを検討してください。







Let vs const



let



と同様に、 const



も「ブロック」定義スコープがあります。 違いは、宣言後にconst



の値を変更できないことです。







 const name = 'Zell'; name = 'Sleepy head'; // TypeError: Assignment to constant variable. let name1 = 'Zell'; name1 = 'Sleepy head'; console.log(name1); // 'Sleepy head'
      
      





const



は変更できないため、変更しない変数に使用できます。







モーダルウィンドウを起動するボタンがサイトにあり、そのようなボタンが1つだけあり、変更されないことがわかっているとします。 この場合、 const



使用します。







 const modalLauncher = document.querySelector('.jsModalLauncher');
      
      





可能な限り変数を宣言するときは、常にlet



よりもconst



を優先します。 変数が再割り当てされないという追加のマークを取得します。 その他の場合は、 let



使用let



ます。







次に、矢印関数について考えます。







矢印関数



矢印関数は矢印(=>)で示され、ES6コードのどこでも見ることができます。 この略語は、匿名関数を作成するために使用されます。 function



キーワードが存在する場所であればどこでも使用できます。 例:







 let array = [1,7,98,5,4,2]; // ES5  var moreThan20 = array.filter(function (num) { return num > 20; }); // ES6  let moreThan20 = array.filter(num => num > 20);
      
      





矢印関数は非常に便利です。なぜなら 彼らの助けを借りて、コードを減らすことができ、それによってエラーが隠される可能性のある場所を減らすことができます。 また、それらに書かれたコードは、構文に精通していれば理解しやすくなります。







矢印関数を詳しく見て、それらを認識して使用する方法を学びましょう。







矢印関数の詳細



まず、関数の作成に注意してください。







JavaScriptでは、おそらく次の方法で関数を作成するのが一般的です。







 function namedFunction() { //   } //   namedFunction();
      
      





関数を作成する2番目の方法では、匿名関数を作成して変数に割り当てます。 無名関数を作成するには、関数宣言からその名前を削除する必要があります。







 var namedFunction = function() { //   }
      
      





関数を作成する3番目の方法は、関数を別の関数またはメソッドの引数として直接渡すことです。 このメソッドは、匿名関数で最も一般的です。 以下に例を示します。







 //   callback- button.addEventListener('click', function() { //   });
      
      





ES6の矢印関数は匿名関数の略語であるため、匿名関数が作成される場所であればどこにでも実装できます。







以下のようになります:







 //   const namedFunction = function (arg1, arg2) { /* do your stuff */} //   const namedFunction2 = (arg1, arg2) => {/* do your stuff */} // callback   button.addEventListener('click', function () { //   }) // callback   button.addEventListener('click', () => { //   })
      
      





類似点に注目してください。 基本的に、 function



キーワードを削除し、わずかに異なる場所で矢印=>に置き換えます。







それでは、矢印関数の本質は何ですか? function



を=>?で置き換えるfunction



のみ







実際には、 function



を=>に置き換えるだけではありません。 矢印関数の構文は、次の2つの要因に応じて変更できます。







  1. 必要な引数の数
  2. 暗黙の復帰が必要


最初の要因は、矢印関数に渡される引数数を指します。 引数が1つしか渡されない場合は、引数が囲まれている括弧を省略できます。 引数が不要な場合は、括弧をアンダースコア_



置き換えることができます。







次の例はすべて有効な矢印関数です。







 const zeroArgs = () => {/*   */} const zeroWithUnderscore = _ => {/*   */} const oneArg = arg1 => {/*   */} const oneArgWithParenthesis = (arg1) => {/*   */} const manyArgs = (arg1, arg2) => {/*   */}
      
      





2番目の要因は、 暗黙的な戻り値の必要性を示します。 デフォルトでは、矢印関数は、 コードが1行占めており、中括弧{}で囲まれていない場合、returnキーワードを自動的に作成します。







したがって、以下は2つの同等の例です。







 const sum1 = (num1, num2) => num1 + num2 const sum2 = (num1, num2) => { return num1 + num2 }
      
      





これらの2つの要因は、上記でmoreThan20



したmoreThan20



moreThan20



、コード削減の基礎として機能します。







 let array = [1,7,98,5,4,2]; // ES5  var moreThan20 = array.filter(function (num) { return num > 20; }); // ES6  let moreThan20 = array.filter(num => num > 20);
      
      





結論として、矢印関数は非常に優れています。 少し時間をかけてそれらをテストした後、それらに慣れ、どこでも使用できます。







矢印関数の「サポーター」に参加する前に、他の機能を知ることになります。これにより、多くの混乱が生じます。つまり、 字句の this



です。







レキシカル本



this



は、呼び出しのコンテキストによって意味が異なる一意のキーワードです。 関数の外部から呼び出された場合、 this



はブラウザのWindow



オブジェクトを参照します。







 console.log(this); // Window
      
      











this



単純な関数を介して呼び出されると、グローバルオブジェクトを参照します。 ブラウザの場合、 this



は常にWindow



ます。







 function hello () { console.log(this); } hello(); // Window
      
      





JavaScriptは、単純な関数を呼び出すときthis



常にブラウザーウィンドウに設定します。 これは、 setTimeout



タイプのタイマー関数でthis



Window



指している理由を説明しています。







this



オブジェクトメソッドで呼び出されると、オブジェクト自体を参照します。







 let o = { sayThis: function() { console.log(this); } } o.sayThis(); // o
      
      











コンストラクター関数を呼び出すとき this



構築されるオブジェクトを参照します







 function Person (age) { this.age = age; } let greg = new Person(22); let thomas = new Person(24); console.log(greg); // this.age = 22 console.log(thomas); // this.age = 24
      
      











イベントハンドラーで使用される場合、 this



はイベントをトリガーした要素を指します。







 let button = document.querySelector('button'); button.addEventListener('click', function() { console.log(this); // button });
      
      





上記の状況からわかるように、この値はそれを呼び出す関数によって決定されます。 各関数は、 this



独自の値を設定します。







矢印関数では、関数がどのように呼び出されても this



は決して新しい意味を持ちません。 this



は、矢印関数を囲むコードで常にthis



と同じ意味を持ちます。 ちなみに、字句は参照(接続)することを意味します。そのため、私が信じているように、字句はthis



名前を取得しました。







わかりにくいので、実際の例をいくつか見てみましょう。







まず、 矢印メソッドを使用してオブジェクトメソッドを宣言しないください。 必要に応じて、 this



を介してオブジェクトを参照できなくなります。







 let o = { //   notThis: () => { console.log(this); // Window this.objectThis(); // Uncaught TypeError: this.objectThis is not a function }, //   objectThis: function () { console.log(this); // o } //      objectThis2 () { console.log(this); // o } }
      
      





第二に、矢印関数イベントハンドラーの作成に適さない場合があります。 this



は、イベントハンドラがバインドされている要素に割り当てられなくなります。







ただし、 event.currentTarget



this



ための正しいコンテキストをいつでも取得できます。 このため、「 適合しない可能性がある」と言われていました







 button.addEventListener('click', function () { console.log(this); // button }); button.addEventListener('click', e => { console.log(this); // Window console.log(event.currentTarget); // button });
      
      





第三に、字句のthis



は、 this



バインディングが予期せず変更される可能性がある状況で使用できます。 例としては、タイマー機能があります。タイマー機能では、 this



that



またはself



愚かさを扱う必要はありません。







 let o = { //   oldDoSthAfterThree: function () { let that = this; setTimeout(function () { console.log(this); // Window console.log(that); // o }) }, //     doSthAfterThree: function () { setTimeout(() => { console.log(this); // o }, 3000) } }
      
      





このアプリケーションは、しばらくしてからクラスを追加または削除する必要がある場合に特に便利です。







 let o = { button: document.querySelector('button'); endAnimation: function () { this.button.classList.add('is-closing'); setTimeout(() => { this.button.classList.remove('is-closing'); this.button.classList.remove('is-open'); }, 3000) } }
      
      





結論として、 moreThan20



上記の例のように、 moreThan20



場所で矢印関数を使用しmoreThan20



コードを簡潔かつ簡潔にmoreThan20



ます。







 let array = [1,7,98,5,4,2]; let moreThan20 = array.filter(num => num > 20);
      
      





デフォルトのオプション



ES6のデフォルトパラメータを使用すると、関数を作成するときにデフォルトパラメータを設定できます。 これがどれほど役立つかを理解するために例を見てみましょう。







チームプレーヤーの名前をアナウンスする関数を作成します。 この関数をES5で作成すると、次のようになります。







 function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName); } announcePlayer('Stephen', 'Curry', 'Golden State Warriors'); // Stephen Curry, Golden State Warriors
      
      





一見したところ、すべてがコードに沿っていると思われます。 しかし、突然、どのチームのメンバーでもないプレーヤーを発表する必要がありますか?







teamName



をスキップすると、現在のコードは単にタスクを処理しません。







 announcePlayer('Zell', 'Liew'); // Zell Liew, undefined
      
      





明らかに、 undefined



はチーム名ではありません。







プレーヤーがいずれのチームにも属していない場合、 Zell Liew, unaffiliated



を発表すると、 Zell Liew, undefined



方が意味があります。 同意しますか?







teamName



Zell Liew, unaffiliated



teamName



announcePlayer



ために、オプションとして、 teamName



代わりにteamName



行を渡すことができます:







 announcePlayer('Zell', 'Liew', 'unaffiliated'); // Zell Liew, unaffiliated
      
      





このアプローチは機能しますが、 teamName



確認することにより、 announcePlayer



を改善する方がteamName



です。







ES5では、リファクタリングされたコードは次のようになります。







 function announcePlayer (firstName, lastName, teamName) { if (!teamName) { teamName = 'unaffiliated'; } console.log(firstName + ' ' + lastName + ', ' + teamName); } announcePlayer('Zell', 'Liew'); // Zell Liew, unaffiliated announcePlayer('Stephen', 'Curry', 'Golden State Warriors'); // Stephen Curry, Golden State Warriors
      
      





または、三項演算子の知識があれば、より短いオプションが可能です。







 function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated'; console.log(firstName + ' ' + lastName + ', ' + team); }
      
      





ES6では、デフォルトのオプションを使用して、オプションを指定するたびに等号=を追加できます。 このアプローチでは、パラメーターが定義されていない場合、ES6は自動的にデフォルト値を割り当てます。







そのため、以下のコードでは、 teamName



定義されていない場合、 teamName



teamName



のデフォルト値を取ります。







 const announcePlayer = (firstName, lastName, teamName = 'unaffiliated') => { console.log(firstName + ' ' + lastName + ', ' + teamName); } announcePlayer('Zell', 'Liew'); // Zell Liew, unaffiliated announcePlayer('Stephen', 'Curry', 'Golden State Warriors'); // Stephen Curry, Golden State Warriors
      
      





便利ですね。







もう1つの瞬間に注目しましょう。 デフォルト値を有効にする場合は、 undefined



手動で渡すことができます。 このようなundefined



手動送信は、デフォルトパラメータが関数の最後の引数でない場合に行われます。







 announcePlayer('Zell', 'Liew', undefined); // Zell Liew, unaffiliated
      
      





上記は、デフォルトのオプションについて知っておくべきことです。 十分にシンプルで非常に便利です。








All Articles