【朝の読書会】上海@ jean-lee「ES6標準紹介」ノート
序文
この記事は、 Shanghai @ jean-leeのメモを読んでから3回目の活動交換を読んでいる朝です。
ここから始まります〜
モジュール
ES6モジュールの設計上の考え方は、モジュールの依存関係、および入力変数と出力変数をコンパイル時に決定できるように、可能な限り静的にすることです。ES6モジュールはオブジェクトではありませんが、出力コードはexportコマンドで明示的に指定され、importコマンドで入力されます。
ES6モジュールの利点:
静的負荷
UMDモジュール形式は不要になりました。将来的には、サーバーとブラウザーでES6モジュール形式がサポートされる予定です。現在、さまざまなツールライブラリを通じて、これは実際に達成されています。
将来的には、ブラウザーの新しいAPIをモジュール形式で提供できるようになり、ナビゲーターオブジェクトのグローバル変数または属性を作成する必要がなくなります。オブジェクト(Mathオブジェクトなど)は名前付けとして必要なくなり、これらの関数は将来モジュールを通じて提供される可能性があります。
厳密モード
厳密モードには、次の制限があります。
変数は使用前に宣言する必要があります
関数パラメーターに同じ名前の属性を含めることはできません。同じ名前を指定しないと、エラーが報告されます。
ステートメントでは使用できません
読み取り専用属性に値を割り当てることはできません。そうしないと、エラーが報告されます
プレフィックス0を使用して8進数を表すことはできません。使用しない場合、エラーが報告されます。
削除できない属性は削除できません。削除しないと、エラーが報告されます
変数deletepropは削除できません。エラーが報告され、属性delete global [prop]のみを削除できます。
evalはその外側のスコープに変数を導入しません
evalとargumentsは再割り当てできません
引数は関数パラメーターの変更を自動的に反映しません
使用できませんarguments.callee
使用できませんarguments.caller
これがグローバルオブジェクトを指さないようにします
fn.callerおよびfn.argumentsを使用して関数呼び出しのスタックを取得することはできません
予約済みの単語(保護、静的、インターフェイスなど)を追加しました
エクスポートコマンド
モジュール機能は、主にexportとimportの2つのコマンドで構成されています。exportコマンドは、モジュールの外部インターフェイスを指定するために使用され、importコマンドは、他のモジュールによって提供される機能を入力するために使用されます。
モジュールは独立したファイルです。ファイル内のすべての変数を外部から取得することはできません。外部がモジュール内の変数を読み取れるようにする場合は、exportキーワードを使用して変数をエクスポートする必要があります。以下は、exportコマンドを使用して変数を出力するJSファイルです。
上記のコードはexportコマンドの後にあり、中括弧を使用してエクスポートする変数のセットを指定しています。これは、以前の書き込み方法(varステートメントの直前に配置)と同等ですが、この書き込み方法を優先する必要があります。このようにして、スクリプトの最後に出力される変数を明確に確認できるためです。
変数の出力に加えて、exportコマンドは関数またはクラスを出力することもできます。
上記のコードは、関数multiplyを外部に出力します。
上記のコードでは、asキーワードを使用して、関数v1およびv2の外部インターフェイスの名前を変更しています。名前を変更した後、v2は異なる名前で2回出力できます。
exportコマンドは外部インターフェースを指定し、モジュール内の変数と1対1の対応を確立する必要があることに注意することが重要です。
//エラーエクスポート1;
//エラーレポートvarm = 1; export m;上記の2つの書き込み方法では、外部インターフェイスが提供されていないため、エラーが報告されます
exportステートメントによって出力されたインターフェイスとそれに対応する値は動的にバインドされます。つまり、モジュール内のリアルタイム値は、このインターフェイスを介して取得できます。
上記のコードは変数fooを出力し、値はbarで、500ミリ秒後にbazになります。
exportコマンドは、モジュールの最上位にある限り、モジュール内のどこにでも表示できます。ブロックレベルのスコープ内にある場合、静的に最適化できないため、エラーが報告されます。
重要なコマンド
importコマンドを使用して、exportコマンドで定義されたモジュールの外部インターフェイスをロードします。
importコマンドは、他のモジュールからインポートする変数の名前を指定する1組の括弧を受け入れます。中括弧内の変数名は、インポートされたモジュール(profile.js)の外部インターフェイスの名前と同じである必要があります。
パスのないモジュール名のみの場合は、JavaScriptエンジンにモジュールの場所を通知する構成ファイルが必要です。
Utilはモジュールファイル名です。パスがないため、このモジュールの取得方法をエンジンに指示するように構成する必要があります。
importコマンドにはブースト効果があり、モジュール全体の先頭にブーストされて最初に実行されます。
importの実行はfooの呼び出しよりも早いため、上記のコードはエラーを報告しません。この動作の本質は、コードが実行される前のコンパイルフェーズでimportコマンドが実行されることです。
インポートは静的に実行されるため、式や変数は使用できません。これらの文法構造は実行時にのみ取得できます。
importステートメントはロードされたモジュールを実行するので、次のように書くことができます。
上記のコードはlodashモジュールのみを実行し、値を入力しません。
同じインポートステートメントが複数回実行される場合、複数回ではなく、1回だけ実行されます。インポートステートメントはシングルトンモードです
モジュールの全体的なロード
特定の出力値をロードするように指定することに加えて、全体的なロードを使用することもできます。つまり、アスタリスク(*)を使用してオブジェクトを指定すると、すべての出力値がこのオブジェクトにロードされます。
exportdefaultコマンド
ユーザーがドキュメントを読まずにモジュールをロードできるように便利にするために、exportdefaultコマンドを使用してモジュールのデフォルト出力を指定する必要があります。
// export-default.js export default function(){console.log( 'foo'); }
他のモジュールがモジュールをロードするとき、importコマンドは匿名関数の任意の名前を指定できます。現時点では、importコマンドの後に中括弧は使用されていません。
非匿名関数の前にexportdefaultコマンドを使用することもできます。
export defaultコマンドは、モジュールのデフォルト出力を指定するために使用されます。明らかに、モジュールはデフォルト出力を1つしか持つことができないため、exportdefaultコマンドは1回しか使用できません。したがって、importコマンドの後に括弧を増やす必要はありません。これは、1つのメソッドにしか対応できないためです。
export defaultコマンドを使用すると、入力モジュールは非常に直感的です。例として、入力lodashモジュールを取り上げます。
import _ from'lodash '; importステートメントにデフォルトのメソッドと他の変数を入力する場合は、次のように記述できます。
上記のコードに対応するエクスポートステートメントは次のとおりです。
上記のコードの最後の行は、forEachインターフェイスが公開され、デフォルトで各インターフェイスを指していることを意味します。つまり、forEachと各は同じメソッドを指します。
デフォルト値をエクスポートする場合は、エクスポートのデフォルト値に従うだけで済みます。
輸出入の複合文言
モジュール内で同じモジュールが最初にインポートされてからエクスポートされる場合、importステートメントはexportステートメントと一緒に記述できます。
この方法で、インターフェイスの名前変更とモジュールの全体的な出力を書き込むこともできます。
デフォルトのインターフェースは次のように記述されています。
名前付きインターフェースをデフォルトのインターフェースに変更する表現は次のとおりです。
同様に、デフォルトのインターフェースの名前を名前付きインターフェースに変更することもできます。
モジュールの継承
サークルモジュールを継承するcircleplusモジュールがあるとします。
上記のコードのexport *は、サークルモジュールのすべての属性とメソッドをエクスポートすることを意味します。export *コマンドは、circleモジュールのデフォルトのメソッドを無視することに注意してください。次に、上記のコードはカスタムe変数とデフォルトメソッドを出力します。
このとき、出力する前に、circle属性またはメソッドの名前を変更することもできます。
上記のコードは、circleモジュールのareaメソッドのみが出力され、circleAreaに名前が変更されたことを示しています。
上記モジュールの読み込み方法は以下のとおりです。
上記のコードのimportexpは、circleplusモジュールのデフォルトメソッドがexpメソッドとしてロードされることを意味します。
ES6モジュールのロードの本質
ES6モジュールのロードメカニズムは、CommonJSモジュールとは完全に異なります。CommonJSモジュールの出力は値のコピーであり、ES6モジュールの出力は値への参照です。
CommonJSモジュールの出力は、出力値のコピーです。つまり、値が出力されると、モジュール内での変更はこの値に影響しません。ES6モジュールの操作メカニズムはCommonJSとは異なり、モジュール読み込みコマンドimportを検出すると、モジュールは実行されず、動的な読み取り専用参照のみが生成されます。本当に使用する必要がある場合は、モジュールに移動して値を取得します。つまり、ES6の入力は、Unixシステムの「シンボリックリンク」に少し似ています。元の値が変更され、インポート入力の値も変更されます。したがって、ES6モジュールは動的に参照され、値はキャッシュされません。モジュール内の変数は、モジュールが配置されているモジュールにバインドされます。
ブラウザモジュールの読み込み
ES6モジュールを使用したブラウザの構文は次のとおりです。
type属性がmoduleに設定されているため、ブラウザーはこれがES6モジュールであることを認識します。
外部モジュールスクリプト(上記の例ではfoo.js)の場合、注意すべき点がいくつかあります。
スクリプトは自動的に厳密なモジュールを採用します。
スクリプト内の最上位変数は、スクリプト内でのみ有効であり、外部には表示されません。
スクリプト内のトップレベルにあるthisキーワードは、ウィンドウを指す代わりにundefinedを返します。
周期的負荷
「循環依存」とは、スクリプトaの実行がスクリプトbに依存し、スクリプトbの実行がスクリプトaに依存することを意味します。一般に、「周期的負荷」とは、強い結合があることを意味しますが、うまく処理しないと、再帰的な負荷が発生し、プログラムが実行できなくなる可能性がありますので、避けてください。
JavaScript言語の場合、最も一般的な2つのモジュール形式であるCommonJSとES6は、さまざまな方法で「循環ロード」を処理し、さまざまな結果を返します。