Es6-es9-newfeatures

提供:Dev Guides
移動先:案内検索

ES9-新機能

ここでは、ES9の新機能について学びます。 非同期ジェネレータについて理解することから始めましょう。

非同期ジェネレーターと反復

*async* キーワードを使用すると、非同期ジェネレーターを非同期にすることができます。 非同期ジェネレータを定義するための*構文*は以下に与えられています-
async function* generator_name() {
  //statements
}

次の例は、ジェネレータの* next()*メソッドを呼び出すたびにPromiseを返す非同期ジェネレータを示しています。

<script>
   async function* load(){
      yield await Promise.resolve(1);
      yield await Promise.resolve(2);
      yield await Promise.resolve(3);
   }

   let l = load();
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
</script>

上記のコードの出力は次のようになります-

{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}
{value: undefined, done: true}

ループを待つ

非同期反復可能オブジェクトは、promiseを返すため、従来の* for..ofループ*構文を使用して反復することはできません。 ES9では*非同期ループ*をサポートする for await of loop が導入されています。

*for await of loop* を使用するための構文を以下に示します。
  • 各反復で、異なるプロパティの値が variable に割り当てられ、変数はconst、let、またはvarで宣言できます。
  • iterable -反復可能なプロパティが反復されるオブジェクト。
for await (variable of iterable) {
   statement
}

次の例は、for await of loopを使用して非同期ジェネレーターを反復処理する方法を示しています。

<script>
   async function* load(){
      yield await Promise.resolve(1);
      yield await Promise.resolve(2);
      yield await Promise.resolve(3);
   }

   async function test(){
      for await (const val of load()){
         console.log(val)
      }
   }
   test();
   console.log('end of script')
</script>

上記のコードの出力は以下のようになります-

end of script
1
2
3

次の例では、for await ofループを使用して配列を反復しています。

<script>
   async function fntest(){
      for await (const val of [10,20,30,40]){
         console.log(val)
      }
   }
   fntest();
   console.log('end of script')
</script>

上記のコードの出力は次のようになります-

end of script
10
20
30
40

レスト/スプレッドプロパティ

ES9は、オブジェクトでのRestおよびSpreadオペレーターの使用をサポートしています。

例:オブジェクトおよびレストオペレーター

次の例は、オブジェクトでのRESTオペレーターの使用を示しています。 学生の年齢プロパティの値は年齢変数にコピーされ、残りのプロパティの値は残りの構文 `…​`を使用して他の変数にコピーされます。

<script>
   const student = {
      age:10,
      height:5,
      weight:50
   }
   const {age,...other} = student;
   console.log(age)
   console.log(other)
</script>

上記のコードの出力は以下のようになります-

10
{height: 5, weight: 50}

例:オブジェクトおよびスプレッド演算子

スプレッド演算子を使用して、複数のオブジェクトを結合したり、オブジェクトを複製したりできます。 これは、次の例に示されています-

<script>
  //spread operator
   const obj1 = {a:10,b:20}
   const obj2={c:30}
  //clone obj1
   const clone_obj={...obj1}
  //combine obj1 and obj2
   const obj3 = {...obj1,...obj2}
   console.log(clone_obj)
   console.log(obj3)
</script>

上記のコードの出力は以下のようになります-

{a: 10, b: 20}
{a: 10, b: 20, c: 30}

約束:いよいよ()

  • finally()は、その結果に関係なく、promiseが解決されるたびに実行されます。 この関数はpromiseを返します。 これは、promiseの then()ハンドラーと catch()*ハンドラーの両方でコードの重複を回避するために使用できます。

構文

下記の構文は、* finally()*関数用です。

promise.finally(function() {
});
promise.finally(()=> {
});

次の例では、3秒の遅延後に正数の2乗を返す非同期関数を宣言しています。 負の数が渡されると、関数はエラーをスローします。 finallyブロックのステートメントは、約束が拒否されたか解決されたかにかかわらず、どちらの場合でも実行されます。

<script>
   let asyncSquareFn = function(n1){
      return new Promise((resolve,reject)=>{
         setTimeout(()=>{
            if(n1>=0){
               resolve(n1*n1)
            }
            else reject('NOT_POSITIVE_NO')
         },3000)
      })
   }
   console.log('Start')

   asyncSquareFn(10)//modify to add -10
   .then(result=>{
      console.log("result is",result)
   }).catch(error=>console.log(error))
   .finally(() =>{
      console.log("inside finally")
      console.log("executes all the time")
   })

   console.log("End");
</script>

上記のコードの出力は次のようになります

Start
End
//after 3 seconds
result is 100
inside finally
executes all the time

テンプレートリテラルリビジョン

ES7以降、タグ付きテンプレートは次のエスケープシーケンスのルールに準拠しています-

  • Unicodeエスケープシーケンスは "\ u" を使用して表されます(例: \ u2764 \ uFE0F
  • Unicodeコードポイントのエスケープシーケンスは "\ u \ {}" を使用して表されます(例: \ u \ {2F}
  • 16進数のエスケープシーケンスは "\ x" を使用して表されます(例: \ xA8
  • 8進リテラルエスケープシーケンスは ""を使用して表され、1つ以上の数字が続きます(例: \ 125

ES2016以前では、タグ付き関数で無効なエスケープシーケンスを使用すると、以下に示すように構文エラーがスローされます-

//tagged function with an invalid unicode sequence
myTagFn`\unicode1`
//SyntaxError: malformed Unicode character escape sequence

ただし、以前のバージョンとは異なり、ES9は無効なUnicodeシーケンスを未定義に解析し、エラーをスローしません。 これは、次の例に示されています-

<script>
   function myTagFn(str) {
      return { "parsed": str[0] }
   }
   let result1 =myTagFn`\unicode1`//invalid unicode character
   console.log(result1)
   let result2 =myTagFn`\u2764\uFE0F`//valid unicode
   console.log(result2)
</script>

上記のコードの出力は以下のようになります-

{parsed: undefined}
{parsed: "❤️"}

生ストリング

ES9では特別なプロパティ raw が導入され、タグ関数の最初の引数で使用できます。 このプロパティを使用すると、エスケープシーケンスを処理せずに、入力されたままの文字列にアクセスできます。

<script>
   function myTagFn(str) {
      return { "Parsed": str[0], "Raw": str.raw[0] }
   }
   let result1 =myTagFn`\unicode`
   console.log(result1)

   let result2 =myTagFn`\u2764\uFE0F`
   console.log(result2)
</script>

上記のコードの出力は次のようになります-

{Parsed: undefined, Raw: "\unicode"}
{Parsed: "❤️", Raw: "\u2764\uFE0F"}

正規表現機能

正規表現では、ドット演算子またはピリオドを使用して単一の文字を照合します。 。 ドット演算子*は、以下の例に示すように、 *\ n、\ r のような改行文字をスキップします-

console.log(/Tutorials.Point/.test('Tutorials_Point'));//true
console.log(/Tutorials.Point/.test('Tutorials\nPoint'));//false
console.log(/Tutorials.Point/.test('Tutorials\rPoint'));//false

正規表現パターンは/* regular_expression/.として表されます。test()メソッドは文字列パラメーターを取り、正規表現パターンを検索します。 上記の例では、 test()メソッド*は、Tutorialsで始まり、任意の1文字が続き、Pointで終わるパターンを検索します。 チュートリアルとポイントの間の入力文字列で \ n または \ r を使用すると、test()メソッドはfalseを返します。

true
false
false

ES9では、* DotAllFlag(\ s)*という新しいフラグが導入されました。これをRegexで使用して、行末記号と絵文字を一致させることができます。 これは、次の例に示されています-

console.log(/Tutorials.Point/s.test('Tutorials\nPoint'));
console.log(/Tutorials.Point/s.test('Tutorials\rPoint'));

上記のコードの出力は以下のようになります-

true
true

名前付きキャプチャグループ

ES9以前は、キャプチャグループはインデックスによってアクセスされていました。 ES9では、キャプチャグループに名前を割り当てることができます。 同じための構文は以下のとおりです-

(?<Name1>pattern1)

const birthDatePattern =/(?<myYear>[0-9]{4})-(?<myMonth>[0-9]{2})/;
const birthDate = birthDatePattern.exec('1999-04');
console.log(birthDate.groups.myYear);
console.log(birthDate.groups.myMonth);

上記のコードの出力は以下のとおりです-

1999
04