Share
Embed
ES2021/2022
kiyoshi yamashita
September 09, 2022
Transcript
30 slides
-
ESのバージョンとは ESはECMAScriptの略でJavaScriptの標準規格。 ES2015(ES6)以降は毎年新しいバージョンがリリースされている。 バージョン リリース時期 1 1997年6月 2 1998年6月 3
1999年12月 4 破棄 5 2009年12月 5.1 2011年6月 -
ECMAScriptの仕様決定プロセス 仕様に追加する機能がそれぞれ個別の提案として、5段階のステージに分けられる。 2か月に1度、ステージをすすめるかどうか議論する。 毎年6月頃にステージ4まで進んでいる機能をリリース。 参考:https://tc39.es/process-document/ ステージ ステージの概要 0 アイディアの段階 1
機能提案の段階 2 機能の仕様書ドラフトを作成した段階 3 仕様としては完成しており、ブラウザの実装やフィード バックを求める段階 4 仕様策定が完了 -
replaceAll 構文:文字列.replaceAll(文字列or正規表現,文字列) 既に存在するreplaceメソッドでは最初に一致した箇所のみしか書き換えられなかった。 そのため、replaceメソッドで全ての文字を置換するには正規表現を使う必要があった。 replaceAllメソッドが追加されたことで一致したすべての箇所を書き換えることが可能。 // これまでの書き方 "すもももももももものうち".replace(/も/g, 'MO'); //
replaceAllを使った書き方 "すもももももももものうち".replaceAll("も", "MO"); // すMOMOMOMOMOMOMOMOのうち 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll -
Promise.any 構文:Promise.any(Promiseの配列) 引数に渡されたPromiseのうち最初にresolveされたものを返す。 引数に与えられたPromiseが全てrejectedされた場合はErrorをグループ化する AggregateErrorが投げられる。 使いどころとしては商品画像をキャッシュまたはサーバーから取得したいとき(一番早く返 された物を使う)など const promise1 =
Promise.reject(0); const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick')); const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow')); const promises = [promise1, promise2, promise3]; Promise.any(promises).then((value) => console.log(value)); -
Promise.anyとPromise.raceの違い Promise.any - 引数のPromiseが最初にresolveした時点で終了 Promise.race - 引数のPromiseが最初にresolveかrejectした時点で終了 - 使いどころとしては長いリクエストを送る場合などに、タイムアウト機能を実装するとき (一定時間たったらrejectを返すようにする)など
const promise1 = new Promise((_,reject) => setTimeout(reject, 10, 'quick_reject')); const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick_resolve')); const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow_resolve')); const promises = [promise1, promise2, promise3]; Promise.race(promises).then((value) => console.log(value)).catch((error) => { console.log(error) }); // rejectが一番初めに解決されるpromise1のquick_rejectが出力される -
ES2020の復習)Null合体演算子 構文:a??b ES2020でNull合体演算子(??)が追加された。 ??演算子では左辺aがnullish(nullまたはundefined)の場合に右の値bを返して、 それ以外の場合に左の値を返す。 const foo = null ??
'default string' ; console.log(foo); // default stringが出力される const baz = 0 ?? 42; console.log(baz); // 0が出力される -
Null合体代入 構文:a??=b Null合体代入では左辺aがnullish(nullまたはundefined)の場合に右の値bを代入する。 この構文を使うことで、初期値を設定するときに余計な分岐が不要になり実装がスッキリす る。 const a = { duration:
50 }; a.duration ??= 10; console.log(a.duration); // 50が出力される a.speed ??= 25; console.log(a.speed); // 25が出力される aがnullish aがnullishではない aに代入される値 b 代入されない -
論理和代入 構文:a||=b aがfalsyな場合に、aにbを代入する。 let a = 0; a ||= 10;
// aはfalsyな値なので10が代入される console.log(a); // 10が出力される let b = 1 b ||= 10; // bはtruthyな値なので代入されない console.log(b); // 1が出力される 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment aがtruthy aがfalsy aに代入される値 代入されない b -
論理積代入 構文:a&&=b 左辺の値aがtruthyな場合に、左辺の値aに右辺の値bを代入する。 let a = 1; a &&= 2;
// aはtruthyな値なので2が代入される console.log(a); // 2 が出力される let b = 0; b &&= 2; // 0はfalsyな値なので代入が行われない console.log(b); // 0 が出力される 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment aがtruthy aがfalsy aに代入される値 b 代入されない -
数値の区切り文字 構文:数値_数値 数値を_(アンダースコア)で区切ることで、数値を読みやすくできる。 注意点 1. 連続して2つ以上のアンダースコアは許可されない(10__000など) 2. アンダースコアを先頭、末尾に置くことはできない(_100, 100_など) 3.
先頭の0のあとにアンダースコアを置くことはできない(0_1など) console.log(100_000_000) // 100000000 が出力される アンダースコアは出力されない 参考 -
WeakRef 構文:new WeakRef(対象) JavaScriptにおいて弱参照を作れるオブジェクト。 構文:WeakRef.prototype.deref(対象) WeakRefオブジェクトの対象オブジェクトを返すか対象オブジェクトが既に回収さ れている場合はundefinedを返す。 let obj =
{ name: "object 1" }; const wref = new WeakRef(obj); console.log(wref.deref()); 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/WeakRef -
Class Fields これまでクラスフィールドを作りたいときはconstructor内で宣言するしかなかった。 ES2022からクラスフィールドが定義できるようになった。 // これまでの書き方 class HogeCounter { constructor
() { this.count = 0; } } // 新しい書き方 class HigeCounter { // publicなクラスフィールド count = 0; } 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/Public_class_fields -
Private Fields ES2022 からprivateフィールドやメソッドも使えるようになった。 privateフィールドには接頭辞に#を付ける。privateフィールドは外部からアクセ スできずに、アクセスしようとすると構文エラーが発生する。 class HogeCounter { #count;
//privateなクラスフィールド constructor(count) { this.#count = count; } // privateなメソッドも作成可能 #doubleCount() { return this.#count * 2; } echoCount() { console .log(this.#doubleCount ()); } } const object = new HogeCounter(10); object.echoCount(); //20が出力される 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/Private_class_fields -
Static Fields ES2022から静的なクラスフィールドやメソッドが使えるようになった。 staticなフィールドやメソッドはインスタンス化なしで使うことが出来る。 class HogeCounter { static count =
10; static echoDoubleCount () { console.log(this.count*2); } } console.log(HogeCounter.count); console.log(HogeCounter.echoDoubleCount ()); 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/static#calling_static_members_from_a_class_constructor_and_other_methods -
.at 構文:array.at(index) インデックス可能なクラス(Array,Stringなど)で指定位置の値を取得可能。 []との違いはat()に負の値を入れることが出来る。 最後の値を取得したいときはarray.at(-1)とすることで取り出せる。 console.log("123456789".at(-1)) // 9が出力する console.log("123456789".at(0)) //
1が出力する 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at -
Top Level await これまではawaitが書けるのはasync関数の中だけだった。async関数の外でもawait 式が書けるようになった。 ただし、関数内では今まで通りasyncが必要。 // NG:関数ではasyncが必要 function hoge()
{ return await hige(); } // OK const result = await hoge(); 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/await#%E6%9C%80%E4%B8%8A%E4%BD%8D%E3%81%AE_await -
Top Level awaitの実行順序 Top Level awaitを使うと実行順序が複雑になる。 Top Level awaitを使用しているファイル全体が1つの非同期関数のように機能する。 //
非同期関数内でawaitを使う場合 console.log("1"); (async () => { await new Promise(resolve => setTimeout((resolve), 3000)) console.log("3") })() console.log("2") モジュールの実行順序への影響:https://qiita.com/uhyo/items/0e2e9eaa30ec2ff05260 // Top Level awaitの場合 console.log("1"); await new Promise(resolve => setTimeout(resolve, 3000)) // await式の評価が終わってから実行される console.log("2") -
Object.hasOwn() Object.hasOwn(オブジェクト,プロパティ) オブジェクトが指定のプロパティを持っているかを真偽値で返す。 class Hoge { hige = 1; }
const hoge = new Hoge(); console.log(Object.hasOwn(hoge, "hige")) // true が返される 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn -
(復習) RegExp Named Capture Groups ES2018から正規表現で?<グループ名>とすることで、マッチした部分にグルー プ名をつけることが出来るようになった。 const regrex =
/好きな食べ物は(?<favFood>.*)です/; const hoge = '好きな食べ物は焼肉 🍖です。'.match(regrex); // グループ名でマッチした部分を取得できる console.log(hoge.groups.favFood) // 焼肉🍖が出力される 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Backreferences -
RegExp Match Indices 正規表現にdフラグを付けることで、indicesプロパティでマッチした文字列の開 始・終了位置を取得できる。 indices:[開始位置, 終了位置]のように配列形式で格納される。 const regrex =
/好きな食べ物は(?<favFood>.*)です/d; const hoge = '好きな食べ物は焼肉 🍖です。'.match(regrex); console.log(hoge.indices.groups.favFood) // 焼肉🍖の開始・終了インデックスである [7,11]が出力される 参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec -
Error Cause エラーが連鎖した場合に、そのエラーの親となるエラーを.causeで辿れる。 親子関係のあるコードで、エラーの発生源を辿るのに便利。 try{ try{ try{ throw new Error('Error1'
); } catch(e){ throw new Error('Error2' , {cause: e}); } }catch(e){ throw new Error('Error3' , {cause: e}); } }catch(e){ console .log(e); // Error3 console .log(e.cause); // Error2 console .log(e.cause.cause); // Error1 } 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause -
Class Static Block JavaScriptでstaticイニシャライザーが使えるようになった。 staticイニシャライザ―ではクラスが読み込まれた時に一度だけ実行される。 staticイニシャライザーが実行されるタイミングでは、インスタンス化されてい ないので、staticではないフィールドに値を入れることはできない。 class Foo{ static
x = 1; static { this.x = 2; console .log("Static initilizer" ); } } console.log(Foo.x); // 2が出力される 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_static_initialization_blocks