[ES6] Ruan Yifeng ES6 学習モジュールの文法

1 はじめに

ES6 以前は、主に と の 2 種類がありましCommonJSAMDサーバーには CommonJS、ブラウザには AMD。ES6 は言語標準レベルでモジュール機能を実装しており、その実装は非常にシンプルで、CommonJS や AMD の仕様を完全に置き換えて、ブラウザとサーバーの共通モジュール ソリューションとなります。大統一段階に入った。

ES6 モジュールの設計思想は、可能な限り静的であることです。コンパイル時間モジュールの依存関係だけでなく、入力変数と出力変数も確認できます。CommonJS モジュールと AMD モジュールは両方とも、以下でのみ使用できます。ランタイムこれらのことを確認してください。

// CommonJS模块
let {
    
     stat, exists, readfile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

この種の読み込みは「実行時読み込み」と呼ばれます。これは、このオブジェクトは実行時にのみ取得できるため、コンパイル時に「静的最適化」を行うことができないためです。

ES6 モジュールはオブジェクトではなく、コマンドによるexport出力とコマンドによる入力を明示的に指定するコードですimport

// ES6模块
import {
    
     stat, exists, readFile } from 'fs';

上記のコードの本質は、fs モジュールから 3 つのメソッドをロードすることであり、他のメソッドはロードされません。この読み込みは、「コンパイル時読み込み」または静的読み込みと呼ばれます。つまり、ES6 はコンパイル時にモジュールの読み込みを完了でき、CommonJS モジュールの読み込みよりも効率的です。もちろん、ES6 モジュール自体はオブジェクトではないため、これにより ES6 モジュール自体を参照することもできなくなります。

2.ストリクトモード

ES6 モジュールは、モジュール ヘッダーに追加するかどうかに関係なく、厳密モードを自動的に採用します"use strict"

Strict モードには主に以下の制限があります。

  • 変数は使用する前に宣言する必要があります
  • 関数のパラメータに同じ名前の属性を含めることはできません。そうでない場合は、エラーが報告されます。
  • with ステートメントは使用できません
  • 読み取り専用属性に値を割り当てることはできません。割り当てないとエラーが報告されます。
  • 削除できない属性は削除できません。削除しないとエラーが報告されます。
  • 変数は削除できませんdelete prop。エラーが報告されます。削除できるのは属性のみです。delete global[prop]
  • eval外部スコープに変数を導入しません
  • evalarguments再割り当てはできませ
  • arguments関数パラメータの変更は自動的に反映されません
  • 故障中arguments.callee
  • 故障中arguments.caller
  • thisグローバルオブジェクトを指さないでください
  • 関数呼び出しのスタックを使用fn.callerおよび取得できないfn.arguments
  • 予約語(protectedstatic、 などinterface)を追加しました。

3. エクスポートコマンド

モジュール関数は主に と の 2 つのコマンドで構成されexportますimportexportコマンドはモジュールの外部インターフェースを指定するために使用され、importコマンドは他のモジュールが提供する機能を入力するために使用されます。

モジュールは単一のファイルです。ファイル内のすべての変数を外部から取得することはできません。モジュール内の変数を外部から読み取れるようにしたい場合は、exportキーワードを使用して変数を出力する必要があります。以下はコマンド出力変数を使用する JS ファイルですexport

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

// 另一种写法
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {
    
     firstName, lastName, year };

exportコマンドは変数を出力するだけでなく、関数やクラスを出力することもできます。

export function multiply(x, y) {
    
    
  return x * y;
};

上記のコードは関数を外部に出力しますmultiply

通常、export出力変数は元の名前ですが、asキーワードを使用して名前を変更できます。

function v1() {
    
     ... }
function v2() {
    
     ... }

export {
    
    
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

特に注意が必要なのは、exportコマンドが外部インターフェイスを指定しており、モジュール内の変数と 1 対 1 の対応を確立する必要があることです。

// 报错
export 1;

// 报错
var m = 1;
export m;

上記 2 つの書き方では、外部インターフェイスが提供されていないため、エラーが報告されます。1 つ目の書き方は直接出力する方法1、2 つ目の書き方は変数を介してm直接出力する方法です11インターフェイスではなく、単なる値です。正しい書き方は以下の通りです。

// 写法一
export var m = 1;

// 写法二
var m = 1;
export {
    
    m};

// 写法三
var n = 1;
export {
    
    n as m};

外部インターフェース m を指定する上記 3 つの記述方法はすべて正しいです。他のスクリプトは、このインターフェイスを通じて値 1 を取得できます。それらの本質は、インターフェイス名とモジュールの内部変数の間に 1 対 1 の対応を確立することです。

同様に、functionとの出力もclassこの書き方に従う必要があります。

// 报错
function f() {
    
    }
export f;

// 正确
export function f() {
    
    };

// 正确
function f() {
    
    }
export {
    
    f};

4.インポートコマンド

コマンドを使用してexportモジュールの外部インターフェイスを定義した後、他の JS ファイルはimportコマンドを通じてこのモジュールをロードできます。

// main.js
import {
    
     firstName, lastName, year } from './profile.js';

function setName(element) {
    
    
  element.textContent = firstName + ' ' + lastName;
}

入力変数の名前を変更する場合、importコマンドはasキーワードを使用して入力変数の名前を変更する必要があります。

import {
    
     lastName as surname } from './profile.js';

importコマンドの本質は入力インターフェイスであるため、コマンドによって入力される変数はすべて読み取り専用です。つまり、モジュールをロードするスクリプト内のインターフェイスを書き換えることはできません。

import {
    
    a} from './xxx.js'

a = {
    
    }; // Syntax Error : 'a' is read-only;

上記のコードでは、スクリプトは変数 をロードしますa。変数が再割り当てされると、 a は読み取り専用インターフェイスであるため、エラーが報告されます。ただし、aオブジェクトの場合は、aプロパティのオーバーライドが許可されます。

import {
    
    a} from './xxx.js'

a.foo = 'hello'; // 合法操作

5. モジュールの全体的なロード

特定の出力値をロードするように指定することに加えて、全体的なロード、つまりアスタリスク (*) を使用してオブジェクトを指定することもでき、すべての出力値がこのオブジェクトにロードされます。

以下は、エリアと円周の 2 つのメソッドをエクスポートする Circle.js ファイルです。

// circle.js

export function area(radius) {
    
    
  return Math.PI * radius * radius;
}

export function circumference(radius) {
    
    
  return 2 * Math.PI * radius;
}

次に、このモジュールをロードします。

// main.js

import {
    
     area, circumference } from './circle';

console.log('圆面积:' + area(4));
console.log('圆周长:' + circumference(14));

上記はロードするメソッドを一つずつ指定する方法で、全体のロード方法は以下の通りです。

import * as circle from './circle';

console.log('圆面积:' + circle.area(4));
console.log('圆周长:' + circle.circumference(14));

モジュールが全体としてロードされるオブジェクト (上の例では円) は静的に分析可能である必要があるため、実行時の変更は許可されないことに注意してください。以下の書き込みは禁止です。

import * as circle from './circle';

// 下面两行都是不允许的
circle.foo = 'hello';
circle.area = function () {
    
    };

6. デフォルトコマンドのエクスポート

このコマンドを使用するときimport、ユーザーはロードする変数または関数の名前を知っている必要があります。そうでないと、ロードできません。ただし、ユーザーは間違いなくすぐに使い始めたいと考えており、ドキュメントを読みたがらない可能性があります。したがって、便宜上、このコマンドはexport defaultモジュールのデフォルト出力を指定するために使用されます。

// export-default.js
export default function () {
    
    
  console.log('foo');
}

上記のコードはモジュール ファイルでありexport-default.js、そのデフォルトの出力は関数です。

他のモジュールがこのモジュールをロードするとき、importコマンドは匿名関数に任意の名前を指定できます。

// import-default.js
import customName from './export-default';
customName(); // 'foo'

上記コードのコマンドでは、出力メソッドをimport指す任意の名前を使用できますが、この時点では、元のモジュールが出力する関数名を知る必要はありません。現時点ではコマンドの後に中括弧が使用されていないexport-default.jsことに注意してください。import

export default非匿名関数の前にコマンドを使用することもできます。

// export-default.js
export default function foo() {
    
    
  console.log('foo');
}

// 或者写成

function foo() {
    
    
  console.log('foo');
}

export default foo;

上記のコードでは、foo関数の関数名がfooモジュール外では無効です。ロード時は無名関数ロードとみなされます。

// 第一组
export default function crc32() {
    
     // 输出
  // ...
}

import crc32 from 'crc32'; // 输入

// 第二组
export function crc32() {
    
     // 输出
  // ...
};

import {
    
    crc32} from 'crc32'; // 输入

上記の 2 つのグループのコードが記述されており、最初のグループは使用されexport default、対応するステートメントは中括弧を使用するimport必要がありません。2 番目のグループは使用されずexport default、対応するimportステートメントは中括弧を使用する必要があります。

exportdefault コマンドは、モジュールのデフォルト出力を指定するために使用されます。明らかに、モジュールはデフォルト出力を 1 つしか持つことができないため、exportdefault コマンドは 1 回しか使用できません。したがって、インポート コマンドの後に中括弧を使用する必要はありません。これは、エクスポート デフォルト コマンドにのみ対応できるためです。

本質的には、という名前の変数またはメソッドexport defaultをエクスポートすることでありdefault、システムではそれに任意の名前を付けることができます。したがって、次の記述は有効です。

// modules.js
function add(x, y) {
    
    
  return x * y;
}
export {
    
    add as default};
// 等同于
// export default add;

// app.js
import {
    
     default as foo } from 'modules';
// 等同于
// import foo from 'modules';

7. エクスポートとインポートの複合記述

モジュール内で、同じモジュールが最初に入力され、次に出力される場合、importステートメントをexportステートメントと一緒に記述することができます。

export {
    
     foo, bar } from 'my_module';

// 可以简单理解为
import {
    
     foo, bar } from 'my_module';
export {
    
     foo, bar };

上記のコードでは、exportANDimportステートメントを結合して 1 行に記述することができます。fooただし、と は1 行で記述された後、bar実際には現在のモジュールにインポートされるのではなく、これら 2 つのインターフェイスを外部に転送するのと同等であるため、現在のモジュールはfooと を直接使用できないことに注意してくださいbar

インターフェイスの名前変更とモジュールの全体的な出力もこの方法で記述することができます。

// 接口改名
export {
    
     foo as myFoo } from 'my_module';

// 整体输出
export * from 'my_module';

デフォルトのインターフェースは次のように書かれています。

export {
    
     default } from 'foo';

名前付きインターフェースをデフォルトインターフェースに変更する記述方法は以下のとおりです。

export {
    
     es6 as default } from './someModule';

// 等同于
import {
    
     es6 } from './someModule';
export default es6;

同様に、デフォルトのインターフェースの名前を名前付きインターフェースに変更することもできます。

export {
    
     default as es6 } from './someModule';

ES2020以前はimport文はありましたが、対応する複合記述方法はありませんでした。

import * as someIdentifier from "someModule";

ES2020ではこの書き方が追加されました。

export * as ns from "mod";

// 等同于
import * as ns from "mod";
export {
    
    ns};

おすすめ

転載: blog.csdn.net/Bon_nenul/article/details/128315440