ホームページ >ウェブフロントエンド >jsチュートリアル >ES6 のモジュールの詳細な紹介 (例付き)

ES6 のモジュールの詳細な紹介 (例付き)

不言
不言転載
2018-12-06 16:08:292638ブラウズ

この記事では、ES6 のモジュールについて詳しく説明します (例を示します)。必要な方は参考にしていただければ幸いです。 。

この記事では、ES6 の新機能であるモジュール Module の使い方を中心に紹介し、モジュール Module の概念と機能を簡単に説明し、モジュール Module の使用方法と注意点を分析します。必要なもの 友人が参照できるもの

1. モジュールの紹介

ES6 のクラスは、オブジェクト指向プログラミングのための単なる構文糖です。 ES5のコンストラクタのプロトタイプチェーン継承の書き方ではモジュール性の問題は解決しません。この問題を解決するためにモジュール機能が提案されています。

歴史的に、JavaScript にはモジュール システムがなかったため、大きなプログラムを相互に依存する小さなファイルに分割し、それらを簡単な方法でアセンブルすることは不可能でした。他の言語にもこの機能があります。

ES6 より前に、コミュニティはいくつかのモジュール読み込みソリューションを開発しましたが、最も重要なものは CommonJS と AMD です。前者はサーバー用、後者はブラウザ用です。 ES6 は言語仕様のレベルでモジュール機能を実装しており、その実装は非常に簡単で、既存の CommonJS および AMD 仕様を完全に置き換えることができ、ブラウザーおよびサーバー用の汎用モジュール ソリューションになります。

ES6 モジュールの設計思想は、モジュールの依存関係をコンパイル時に決定できるようにできる限り静的であることです (この種の読み込みは「コンパイル時読み込み」と呼ばれます)。入力変数と出力変数も同様です。 CommonJS モジュールと AMD モジュールは両方とも、実行時にのみこれらのことを決定できます。
ES6 モジュールを使用するブラウザの構文は次のとおりです。

<script type="module" src="fs.js"></script>

上記のコードは、モジュール fs.js を Web ページに挿入します。type 属性が module に設定されているため、ブラウザはこれが ES6 モジュールであることを認識します。

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

上記のコードは、インポートを通じてモジュールを読み込み、そのメソッドの一部を読み込みます。

2. インポートとエクスポート

モジュール関数は主に、エクスポートとインポートの 2 つのコマンドで構成されます。エクスポート コマンドはモジュールの外部インターフェイスを指定するために使用され、インポート コマンドは他のモジュールが提供する機能を入力するために使用されます。
モジュールは独立したファイルです。このファイル内の変数はすべて外部から取得することはできません。外部からモジュール内の変数を読み取れるようにしたい場合は、export キーワードを使用して変数を出力する必要があります。以下は、export コマンドを使用して変数を出力する JS ファイルです。

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

上記以外にも、export の書き方があります。 (スクリプトの最後にどの変数が出力されているかが一目でわかるので、これをお勧めします。)

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

export コマンドでは、変数の出力に加えて、関数やクラスも出力できます。通常、export で出力される変数は元の名前ですが、 as キーワードを使用して名前を変更できます。

function v1() { ... }
function v2() { ... }
export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

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

// main.js
import {firstName, lastName, year} from './profile';
function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

上記のコードのインポート コマンドは、profile.js ファイルをロードし、そこから変数を入力するために使用されます。 import コマンドは、他のモジュールからインポートされる変数の名前を指定するオブジェクト (中括弧で示されています) を受け入れます。中括弧内の変数名は、インポートされたモジュール (profile.js) の外部インターフェイスの名前と同じである必要があります。
入力変数の名前を変更する場合は、インポート コマンドで as キーワードを使用して入力変数の名前を変更します。

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

import コマンドには昇格効果があり、モジュール全体の先頭に昇格して最初に実行されます。

foo();
import { foo } from 'my_module';

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

ロードする特定の出力値を指定することに加えて、全体的なロード、つまりアスタリスクを使用することもできます。 (*) オブジェクトを指定します。すべての出力値がこのオブジェクトにロードされます。
circle.js ファイルがあり、エリアと円周の 2 つのメソッドを出力します。
次に、このモジュールをロードします。

// 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));

4. デフォルトのエクスポート

ユーザーに利便性を提供し、ドキュメントを読まずにモジュールをロードできるようにするには、デフォルトのエクスポート コマンドを使用する必要があります。モジュールのデフォルト出力を指定します。

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

上記のコードはモジュール ファイルexport-default.jsであり、そのデフォルトの出力は関数です。
他のモジュールがこのモジュールをロードするとき、インポート コマンドは匿名関数に任意の名前を指定できます。

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

import コマンドの後には中括弧が使用されないことに注意してください。
基本的に、デフォルトのエクスポートは、デフォルトと呼ばれる変数またはメソッドを出力することであり、システムはそれに任意の名前を付けることができます。この後に変数宣言文を続けることはできません。

// 正确
var a = 1;
export default a;
// 错误
export default var a = 1;

5. ES6 モジュール読み込みの本質

ES6 モジュール読み込みの仕組みは CommonJS モジュールとはまったく異なります。 CommonJS モジュールは値のコピーを出力しますが、ES6 モジュールは値への参照を出力します。
CommonJS モジュールは出力値のコピーを出力します。つまり、値が出力されると、モジュール内の変更はこの値に影響しません。次のモジュール ファイル lib.js の例を見てください。

// lib.js
var counter = 3;
function incCounter() {
 counter++;
}
module.exports = {
 counter: counter,
 incCounter: incCounter,
};

上記のコードは、内部変数 counter と、この変数をオーバーライドする内部メソッド incCounter を出力します。次に、このモジュールを main.js にロードします。

// main.js
var mod = require('./lib');
console.log(mod.counter); // 3
mod.incCounter();
console.log(mod.counter); // 3

上面代码说明,lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。这是因为mod.counter是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。

// lib.js
var counter = 3;
function incCounter() {
 counter++;
}
module.exports = {
 get counter() {
  return counter
 },
 incCounter: incCounter,
};

上面代码中,输出的counter属性实际上是一个取值器函数。现在再执行main.js,就可以正确读取内部变量counter的变动了。
ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,换句话说,ES6的输入有点像Unix系统的“符号连接”,原始值变了,import输入的值也会跟着变。因此,ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
还是举上面的例子。

// lib.js
export let counter = 3;
export function incCounter() {
 counter++;
}
// main.js
import { counter, incCounter } from './lib';
console.log(counter); // 3
incCounter();
console.log(counter); // 4

上面代码说明,ES6模块输入的变量counter是活的,完全反应其所在模块lib.js内部的变化。
由于ES6输入的模块变量,只是一个“符号连接”,所以这个变量是只读的,对它进行重新赋值会报错。

// lib.js
export let obj = {};
// main.js
import { obj } from './lib';
obj.prop = 123; // OK
obj = {}; // TypeError

上面代码中,main.js从lib.js输入变量obj,可以对obj添加属性,但是重新赋值就会报错。因为变量obj指向的地址是只读的,不能重新赋值,这就好比main.js创造了一个名为obj的const变量。
最后,export通过接口,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例。

// mod.js
function C() {
 this.sum = 0;
 this.add = function () {
  this.sum += 1;
 };
 this.show = function () {
  console.log(this.sum);
 };
}
export let c = new C();

上面的脚本mod.js,输出的是一个C的实例。不同的脚本加载这个模块,得到的都是同一个实例。

// x.js
import {c} from './mod';
c.add();
// y.js
import {c} from './mod';
c.show();
// main.js
import './x';
import './y';

现在执行main.js,输出的是1。这就证明了x.js和y.js加载的都是C的同一个实例。

以上がES6 のモジュールの詳細な紹介 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。