JavaScriptガイドパート9:ES7、ES8、およびES9標準の概要

本日、JavaScriptマニュアルの翻訳の第9部では、ES7、ES8、およびES9標準のおかげで言語に登場した機能の概要が作成されます。



パート1:最初のプログラム、言語機能、標準

パート2:コードスタイルとプログラム構造

パート3:変数、データ型、式、オブジェクト

パート4:機能

パート5:配列とループ

パート6:例外、セミコロン、ワイルドカードリテラル

パート7:厳格モード、このキーワード、イベント、モジュール、数学計算

パート8:ES6機能の概要

パート9:ES7、ES8、およびES9標準の概要







ES7標準



公式用語に従ってES2016と呼ばれるES7標準は、2016年夏にリリースされました。 彼は、ES6と比較して、言語にもたらされたのはそれほど新しいものではありません。 特に、次のことについて話している:





ArrayメソッドArray.prototype.includes()



Array.prototype.includes()



メソッドは、配列内の要素の存在を確認するように設計されています。 配列で目的のものを見つけると、find- false



ではなくtrue



返しtrue



。 ES7より前は、 indexOf()



メソッドを使用して同じ操作を実行し、要素が見つかった場合は、配列内で最初に見つかったインデックスを返します。 indexOf()



が要素を見つけられない場合、数値-1



返します。



JavaScriptタイプ変換規則に従って、数値-1



true



変換されtrue



。 その結果、 indexOf()



操作の結果を確認するには、次の形式の特に便利ではない構築を使用する必要があります。



 if ([1,2].indexOf(3) === -1) { console.log('Not found') }
      
      





同様の状況で、 indexOf()



要素を見つけることなくfalse



返すと仮定すると、以下に示すようなものを使用すると、コードは正しく機能しません。



 if (![1,2].indexOf(3)) { // console.log('Not found') }
      
      





この場合、構造![1,2].indexOf(3)



false



を与えるfalse



![1,2].indexOf(3)



false







include includes()



メソッドを使用すると、このような比較はより論理的になります。



 if (![1,2].includes(3)) { console.log('Not found') }
      
      





この場合、構造[1,2].includes(3)



false



返し、この値は演算子!



true



変わり、コンソールは配列内のアイテムが見つからなかったことを示すメッセージを受け取ります。



▍べき乗演算子



べき乗演算子は、 Math.pow()



メソッドと同じ機能を実行しますが、言語の一部であるため、ライブラリ関数よりも使用する方が便利です。



 Math.pow(4, 2) == 4 ** 2 //true
      
      





この演算子は、JSへの快適な追加と見なすことができ、特定の計算を実行するアプリケーションで役立ちます。 他のプログラミング言語にも同様の演算子が存在します。



ES8標準



ES8 Standard(ES2017)は2017年にリリースされました。 彼は、ES7のように、言語に多くをもたらしませんでした。 つまり、次の機能について話している。





given指定された長さに行を追加する



ES8では、 padStart()



およびpadEnd()



2つの新しいString



オブジェクトメソッドが導入されました。



padStart()



メソッドは、最終行が目的の長さに達するまで、現在の行を別の行で埋めます。 行の先頭(左)で塗りつぶしが行われます。 この方法の使用方法は次のとおりです。



 str.padStart(targetLength [, padString])
      
      





ここで、 str



は現在の行、 targetLength



は合計行の長さです(現在の行の長さより短い場合、この行は変更なしで返されます) padString



はオプションのパラメーターです。現在の行を埋めるために使用される行です。 padString



指定されていない場合、スペース文字を使用してpadString



現在の行を指定された長さまで埋め込みます。



padEnd()



メソッドはpadEnd()



似ていpadStart()



が、行は右側で塗りつぶされます。



これらの方法の使用例を検討してください。



 const str = 'test'.padStart(10) const str1 = 'test'.padEnd(10,'*') console.log(`'${str}'`) //'      test' console.log(`'${str1}'`) //'test******'
      
      





ここで、必要な長さの文字列のみでpadStart()



を使用すると、元の文字列の先頭にスペースが追加されました。 padEnd()



を使用して最終行の長さとそれを埋める行を使用すると、文字*



が元の行の末尾に追加されました。



▍メソッドObject.values()



このメソッドは、オブジェクト自体のプロパティの値を含む配列を返します。つまり、プロトタイプチェーンを介してアクセスできるプロパティではなく、オブジェクトに含まれるプロパティの値を返します。



使用方法は次のとおりです。



 const person = { name: 'Fred', age: 87 } const personValues = Object.values(person) console.log(personValues) // ['Fred', 87]
      
      





このメソッドは配列にも適用されます。



▍メソッドObject.entries()



このメソッドは、配列を返します。配列の各要素は、オブジェクトのプロパティのキーと値を[key, value]



形式で含む配列でもあります。



 const person = { name: 'Fred', age: 87 } const personValues = Object.entries(person) console.log(personValues) // [['name', 'Fred'], ['age', 87]]
      
      





このメソッドを配列に適用すると、要素のインデックスがキーとして表示され、対応するインデックスで配列に保存されているものが値として表示されます。



▍getOwnPropertyDescriptors()メソッド



このメソッドは、オブジェクト自体のすべてのプロパティに関する情報を返します。 属性セット(記述子)は、オブジェクトのプロパティに関連付けられています。 特に、次の属性について説明しています。





この方法の使用方法は次のとおりです。



 Object.getOwnPropertyDescriptors(obj)
      
      





プロパティ情報を検索するオブジェクトを受け取り、この情報を含むオブジェクトを返します。



 const person = { name: 'Fred', age: 87 } const propDescr = Object.getOwnPropertyDescriptors(person) console.log(propDescr) /* { name:  { value: 'Fred',    writable: true,    enumerable: true,    configurable: true }, age:  { value: 87,    writable: true,    enumerable: true,    configurable: true } } */
      
      





なぜこの方法が必要なのですか? 実際には、オブジェクトの小さなコピーを作成したり、他のプロパティの中でゲッターやセッターをコピーしたりすることができます。 ES6標準に登場したObject.assign()



メソッドを使用してオブジェクトをコピーすることはできませんでした。



次の例には、 console.log()



を使用して、対応するプロパティに書き込もうとしているものを表示するセッターを持つオブジェクトがあります。



 const person1 = { set name(newName) {     console.log(newName) } } person1.name = 'x' // x
      
      





assign()



メソッドを使用してこのオブジェクトをコピーしてみましょう。



 const person2 = {} Object.assign(person2, person1) person2.name = 'x' //     ,   
      
      





ご覧のとおり、このアプローチは機能しません。 元のオブジェクトのセッターであったname



プロパティは、通常のプロパティとして表されるようになりました。



次に、メソッドObject.defineProperties()



(ES5.1で登場)およびObject.getOwnPropertyDescriptors()



を使用してオブジェクトをコピーします。



 const person3 = {} Object.defineProperties(person3, Object.getOwnPropertyDescriptors(person1)) person3.name = 'x' //x
      
      





ここでは、セッターはオブジェクトのコピーに残ります。



Object.assign()



固有の制限は、オブジェクトを複製するために使用する場合、 Object.create()



メソッドにも固有であることに注意してください。



function関数パラメーターの完了コンマ



この機能により、関数の宣言時および呼び出し時に、パラメーターまたは引数のリストの最後にそれぞれコンマを残すことができます。



 const doSomething = ( var1, var2, ) => { //... } doSomething( 'test1', 'test2', )
      
      





これにより、バージョン管理システムの使いやすさが向上します。 つまり、関数に新しいパラメーターを追加するときに、コンマを挿入するためだけに既存のコードを変更する必要がないという事実について話します。



synchronous非同期関数



async/await



コンストラクトがES2017標準に登場しました。これは、このバージョンの言語の最も重要な革新と見なすことができます。



非同期関数は、promiseとジェネレーターの組み合わせであり、以前は大量のテンプレートコードと不便な一連のpromiseを記述する必要があった構造を簡素化します。 実際、私たちは約定に関する高レベルの抽象化について話している。



ES2015標準に約束が登場したとき、約束は非同期コードの既存の問題を解決するように設計されていました。 しかし、ES2015とES2017の標準を共有する2年間で、約束はこれらの問題の最終的な解決策とは見なされないことが明らかになりました。



特に、約束は「コールバック地獄」の問題を解決することを目的としていましたが、この問題を解決しても、使用されるコードの複雑さのために彼ら自身は最高の面を示しませんでした。 実際、 async/await



コンストラクトはプロミスの問題を解決し、非同期コードの使いやすさを向上させます。



例を考えてみましょう。



 function doSomethingAsync() { return new Promise((resolve) => {     setTimeout(() => resolve('I did something'), 3000) }) } async function doSomething() { console.log(await doSomethingAsync()) } console.log('Before') doSomething() console.log('After')
      
      





このコードは、以下をコンソールに出力します。



 Before After I did something
      
      





ご覧のとおり、 doSomething()



呼び出したAfter



、コンソールにBefore



After



が表示され、3秒が経過した後doSomething()



プログラムを実行し続けI did something







非同期関数のシリアル呼び出し



必要に応じて、非同期関数は呼び出しのチェーンのようなものを形成できます。 そのようなデザインは、約束のみに基づいて、類似のものよりも読みやすさが優れています。 これは次の例で見ることができます。



 function promiseToDoSomething() { return new Promise((resolve)=>{     setTimeout(() => resolve('I did something'), 10000) }) } async function watchOverSomeoneDoingSomething() { const something = await promiseToDoSomething() return something + ' and I watched' } async function watchOverSomeoneWatchingSomeoneDoingSomething() { const something = await watchOverSomeoneDoingSomething() return something + ' and I watched as well' } watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => { console.log(res) // I did something and I watched and I watched as well })
      
      





▍共有メモリとアトミック操作



ここでは、共有メモリ領域を記述することができるSharedArrayBufferオブジェクトと、静的メソッドの形式でアトミック操作のセットを含むAtomicsオブジェクトについて説明しています。 これらのオブジェクトがプログラマーに与える可能性に関する詳細はここで見つけることができます



ES9標準



ES9(ES2018)は、この資料の公開時点での標準の最新バージョンです。 主な機能は次のとおりです。





spreadオブジェクトへのスプレッドおよびレスト演算子の適用



ES6に登場し、配列の操作に使用できる残りの演算子とスプレッド演算子についてはすでに説明しました。 どちらも3つのドットのように見えます。 次の配列の構造化の例では、rest演算子を使用して、その最初と2番目の要素をfirst



second



定数に入れ、残りをすべてothers



定数に入れることができます。



 const numbers = [1, 2, 3, 4, 5] const [first, second, ...others] = numbers console.log(first) //1 console.log(second) //2 console.log(others) //[ 3, 4, 5 ]
      
      





spread



演算子を使用すると、通常のパラメーターリストを期待する関数に配列を渡すことができます。



 const numbers = [1, 2, 3, 4, 5] const sum = (a, b, c, d, e) => a + b + c + d + e const res = sum(...numbers) console.log(res) //15
      
      





同じアプローチを使用して、オブジェクトを操作できるようになりました。 次に、破壊的な代入操作でrestステートメントを使用する例を示します。



 const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 } console.log(first) //1 console.log(second) //2 console.log(others) //{ third: 3, fourth: 4, fifth: 5 }
      
      





以下は、既存のオブジェクトに基づいて新しいオブジェクトを作成するときに使用されるスプレッドステートメントです。 この例は前の例を続けています。



 const items = { first, second, ...others } console.log(items) //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }
      
      





synchronous非同期イテレーター



新しいfor-await-of



構造により、ループでプロミスを返す非同期関数を呼び出すことができます。 そのようなループは、次のステップに進む前に、約束の解決を待ちます。 外観は次のとおりです。



 for await (const line of readLines(filePath)) { console.log(line) }
      
      





同時に、非同期ループではこのようなループを使用する必要があることに注意する必要がありますasync/await



コンストラクトを使用する場合と同じ方法です。



▍Promise.prototype.finally()メソッド



約束が正常に解決されると、次のthen()



メソッドが呼び出されます。 問題が発生した場合、 catch()



メソッドが呼び出されます。 finally()



メソッドを使用すると、前に何が起こったかに関係なくコードを実行できます。



 fetch('file.json') .then(data => data.json()) .catch(error => console.error(error)) .finally(() => console.log('finished'))
      
      





▍正規表現の改善



正規表現には、文字列を遡及的にチェックする機能があります( ?<=



)。 これにより、他の構造が存在する行の前に特定の構造を検索できます。



ES 2018標準の前にJavaScriptで実装された正規表現には、 ?=



Constructを使用してチェックに先行する機能がありました。 このようなチェックにより、行の特定のフラグメントの後に別のフラグメントが続くかどうかがわかります。



 const r = /Roger(?= Waters)/ const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //false console.log(res2) //true
      
      





建設?!



逆の操作を実行します-指定された行の後に別の行が続かない場合にのみ一致が見つかります。



 const r = /Roger(?! Waters)/g const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //true console.log(res2) //false
      
      





遡及検証では、すでに述べたように、 ?<=



構文?<=



使用されます。



 const r = /(?<=Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //false console.log(res2) //true
      
      





説明したものと反対の操作は、構造を使用して実行できます?<!







 const r = /(?<!Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //true console.log(res2) //false
      
      





Unicode正規表現エスケープシーケンス



正規表現では、任意の数字に一致する\d



クラス、任意の空白文字に一致する\s



クラス、任意の英数字に一致する\w



クラスなどを使用できます。 問題の機能は、正規表現で使用できるクラスの範囲を拡張し、Unicodeシーケンスを操作できるようにします。 クラス\p{}



およびクラスの逆\P{}



について話しています。



Unicodeでは、各文字には一連のプロパティがあります。 これらのプロパティは、 \p{}



グループの中括弧で示されています。 たとえば、 Script



プロパティは、文字が属する言語のファミリを決定し、 ASCII



プロパティは論理的であり、ASCII文字についてはtrue



になります。 たとえば、一部の行にASCII文字のみが含まれているかどうかがわかります。



 console.log(r.test('abc')) //true console.log(r.test('ABC@')) //true console.log(r.test('ABC')) //false
      
      





ASCII_Hex_Digit



プロパティは、16進数の書き込みに使用できる文字に対してのみtrue



です。



 const r = /^\p{ASCII_Hex_Digit}+$/u console.log(r.test('0123456789ABCDEF')) //true console.log(r.test('H')) //false
      
      





上記と同じ方法で使用される他の多くの同様のプロパティがあります。 それらの中には、 Uppercase



Lowercase



White_Space



Alphabetic



Emoji



ます。



たとえば、 Script



プロパティを使用して、文字列で使用されるアルファベットを決定する方法を次に示します。 ここでは、ギリシャ語のアルファベットの使用について文字列を確認します。



 const r = /^\p{Script=Greek}+$/u console.log(r.test('ελληνικά')) //true console.log(r.test('hey')) //false
      
      





これらのプロパティの詳細については、 こちらをご覧ください



名前付きグループ



ES2018でキャプチャされた文字グループには名前を付けることができます。 外観は次のとおりです。



 const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ const result = re.exec('2015-01-02') console.log(result) /* [ '2015-01-02', '2015', '01', '02', index: 0, input: '2015-01-02', groups: { year: '2015', month: '01', day: '02' } ] */
      
      





名前付きグループを使用しないと、同じデータは配列要素としてのみ使用可能になります。



 const re = /(\d{4})-(\d{2})-(\d{2})/ const result = re.exec('2015-01-02') console.log(result) /* [ '2015-01-02', '2015', '01', '02', index: 0, input: '2015-01-02', groups: undefined ] */
      
      





正規表現フラグ



s



フラグを使用すると、文字になり.



(ピリオド)は、とりわけ、改行文字と一致します。 このフラグがないと、ピリオドは改行を除くすべての文字に一致します。



 console.log(/hi.welcome/.test('hi\nwelcome')) // false console.log(/hi.welcome/s.test('hi\nwelcome')) // true
      
      





まとめ



この資料で、 この JavaScriptマニュアルの翻訳の出版を完了します。 これらの出版物が、以前にJavaScriptを使用したことがない人でも、この言語でのプログラミングの第一歩を踏み出すのに役立つことを願っています。



親愛なる読者! 以前にJSで作成したことがなく、このガイドでこの言語をマスターしたことがある場合は、感想をお聞かせください。






All Articles