Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: ES2022のサポート #1432

Merged
merged 2 commits into from
Jun 22, 2022
Merged

feat!: ES2022のサポート #1432

merged 2 commits into from
Jun 22, 2022

Conversation

azu
Copy link
Collaborator

@azu azu commented Jun 14, 2022

jsprimer.net がECMAScript 2022(ES2022)に対応しました。

ES2022への対応して、次の内容が更新されています。
また、ウェブ版の仕組みとしてユースケースの章などのHTMLを使ったアプリケーションもウェブ上でそのまま変更しながら確認できるエディタを組み込んでいます。

Top-Level await

https://jsprimer.net/basic/async/#top-level-await-in-module

ES2021までは、await式はAsync Functionの直下でのみしか利用できませんでした。
ES2022には、これに加えてModuleの直下では、Async Functionで囲まなくてもawait式が利用できます。

console.log("start");
// awaitを使って1秒待つ
await new Promise(resolve => setTimeout(resolve, 1000));
console.log("end");

これにより、await式を使うためだけにAsync Functionを使った即時実行関数は不要となります。

// awaitを使うためだけに、Async Functionの即時実行関数を実行している
(async function() {
    // awaitを使う処理
    const result = await doAsyncTask();
    // ...
})();

Object.hasOwn

https://jsprimer.net/basic/object/

ES2022ではObject.hasOwn静的メソッドが追加されました。
Object.hasOwn静的メソッドは、対象のオブジェクトが指定したプロパティを持っているかを確認できるメソッドです。

const obj = { key: "value" };
// `obj`が`key`プロパティを持っているならtrueとなる
if (Object.hasOwn(obj, "key")) {
    console.log("`obj`は`key`プロパティを持っている");
}

このObject.hasOwn静的メソッドは、Object.prototype.hasOwnPropertyメソッドを置き換える目的で導入されています。

hasOwnPropertyメソッドは、Object.create(null)で作成したような"prototypeを継承していないオブジェクト"からは直接呼び出せないという欠点があります。

// prototypeを継承していないオブジェクト
const obj = Object.create(null);
// `Object.prototype`を継承していないため呼び出すと例外が発生する
console.log(obj.hasOwnProperty("key")); // => Error: hasOwnPropertyメソッドは呼び出せない

Object.hasOwn静的メソッドは、インスタンスオブジェクトではなく静的メソッドであるため、対象のオブジェクトに関係なく利用できます。

// prototypeを継承していないオブジェクト
const mapLike = Object.create(null);
// keyは存在しない
console.log(Object.hasOwn(mapLike, "key")); // => false

Array.prototype.at

https://jsprimer.net/basic/array/

配列の末尾の要素へアクセスするには、array[array.length - 1]というlengthプロパティを使う必要がありました。
arrayを2回書く必要があるなど、末尾の要素へのアクセスは少し手間が必要になっていました。

この問題を解決するためES2022では、相対的なインデックスの値を指定して配列の要素へアクセスできるArray.prototype.atメソッドが追加されました。
Arrayのatメソッドは、配列[インデックス]とよく似ていますが、引数には相対的なインデックスの値を引数として渡せます。.at(0)なら配列の先頭の要素へ、.at(-1)なら配列の末尾の要素へアクセスできます。

const array = ["a", "b", "c"];
// 先頭の要素にアクセス
console.log(array.at(0)); // => "a"
console.log(array[0]); // => "a"
// 後ろから1つ目の要素にアクセス
console.log(array.at(-1)); // => "c"
console.log(array[array.length - 1]); // => "c"

String.prototype.at

https://jsprimer.net/basic/string/

配列と同じく文字列にも相対的なインデックスの値を指定して文字へアクセスできるString.prototype.atが追加されました。

const str = "文字列";
console.log(str.at(0)); // => "文"
console.log(str.at(1)); // => "字"
console.log(str.at(2)); // => "列"
console.log(str.at(-1)); // => "列"

Public/Privateクラスフィールド

ES2022ではクラスにクラスフィールド構文が追加されました。

クラスフィールドは、PublicクラスフィールドとPrivateクラスフィールドの2種類があります。
Publicクラスフィールドは、次のようにクラスのインスタンスに対するプロパティを宣言的に定義できる構文です。

class Counter {
    count = 0;
    increment() {
        this.count++;
    }
}
const counter = new Counter();
counter.increment();
console.log(counter.count); // => 1

一方のPrivateクラスフィールドは、フィールド名の前に#をつけることで、クラスの外からはアクセスできないプライベートなプロパティを定義できる構文です。

class NumberWrapper {
    // valueはPrivateクラスフィールドとして定義
    #value;
    constructor(value) {
        this.#value = value;
    }
    // `#value`フィールドの値を返すgetter
    get value() {
        return this.#value;
    }
    // `#value`フィールドに値を代入するsetter
    set value(newValue) {
        this.#value = newValue;
    }
}

const numberWrapper = new NumberWrapper(1);
console.log(numberWrapper.value); // => 1
// クラスの外からPrivateクラスフィールドには直接はアクセスできない
// console.log(numberWrapper.#value); // => SyntaxError: reference to undeclared private field or method #value

今までは、クラスのインスタンスにプロパティを定義するにはクラスのconstructorメソッド内で値を代入する必要がありました。クラスフィールドでは、インスタンスへのプロパティの定義をより宣言的に行えます。

その他

そのほかにもES2022ではRegular expression match indices、スタックトレースを継承するError cause、 static blocksなどが追加されています。

ウェブエディタの改善

jsprimer.net のウェブ版では、JavaScriptのコードをそのままブラウザで実行できるコンソール機能が実装されています。

今までは、JavaScript実行のみしか扱えませんでしたが、そのため表示を扱うユースケースであるTodoアプリなどはローカルサーバを使って確認する必要がありました。
今回、jsprimerにHTMLの表示も伴うコードにも対応したエディタを組み込みました。

clipboard.png
CodeSandboxが提供しているComponent toolkit for creating live-running code editing experiences | Sandpackを使いエディタを組み込んでいます。
エディタの右下のボタンから、CodeSandboxで開いてコードを共有も可能です。

resolve #1337

@azu azu changed the title feat: ES2022のサポート feat!: ES2022のサポート Jun 14, 2022
@bot-user
Copy link

bot-user commented Jun 14, 2022

Deploy Preview for js-primer ready!

Name Link
🔨 Latest commit f021690
🔍 Latest deploy log https://app.netlify.com/sites/js-primer/deploys/62a82bdbbb36680009422da7
😎 Deploy Preview https://deploy-preview-1432--js-primer.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@azu azu marked this pull request as ready for review June 22, 2022 12:48
@azu azu merged commit f4cabcd into master Jun 22, 2022
@azu azu deleted the feature/1337 branch June 22, 2022 12:48
@azu azu restored the feature/1337 branch June 22, 2022 12:49
@azu azu deleted the feature/1337 branch June 22, 2022 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ECMAScript 2022の対応
2 participants