いいえ、require は CommonJS 仕様のモジュール構(gòu)文であり、es6 仕様のモジュール構(gòu)文は import です。 require は実行時(shí)にロードされ、import はコンパイル時(shí)にロードされます。require はコード內(nèi)のどこにでも記述できます。import はファイルの先頭にのみ記述でき、條件文や関數(shù)スコープでは使用できません。モジュール屬性は導(dǎo)入されるだけです。 require を?qū)g行した場(chǎng)合、そのためパフォーマンスは比較的低くなりますが、インポート コンパイル時(shí)に導(dǎo)入されたモジュールのプロパティのパフォーマンスはわずかに高くなります。
このチュートリアルの動(dòng)作環(huán)境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。
require は CommonJS 仕様のモジュール構(gòu)文であり、es6 仕様のモジュール構(gòu)文は import です。
CommonJS の概要
CommonJS は、JavaScript のモジュール化仕様を?qū)g裝し、モジュールの特性とモジュール間の相互依存関係を標(biāo)準(zhǔn)化することで、コードの記述と保守を改善します。コードの再利用性を向上させながら。各ファイルはモジュールとして定義され (モジュール変數(shù)は現(xiàn)在のモジュールを表します)、獨(dú)自のスコープを持ちます。各ファイルで定義された変數(shù)、関數(shù)、クラスはプライベートであり、他のモジュールからは見(jiàn)えません。モジュールのエクスポート屬性は外部インターフェイスであり、エクスポートを通じてエクスポートされた屬性のみをロードして認(rèn)識(shí)できます。 NodeはCommonJS仕様に基づいて実裝されており、CommonJS仕様のモジュールのロードは同期的であり、サーバー內(nèi)のNodeモジュールはサーバーのローカルハードディスクに直接格納されるため、當(dāng)然ロードが高速であると言えます。ノードプロジェクトが現(xiàn)時(shí)點(diǎn)で最良の CommonJS 仕様であること、実用化。
ECMAScript 6 (略稱(chēng) ES6)
ECMAScript は、(European Computer Manufactures Association Script) の略稱(chēng)で、國(guó)際標(biāo)準(zhǔn)化 ECMA によってカスタマイズされた JavaScript スクリプト言語(yǔ)です。標(biāo)準(zhǔn)化された仕様。 ECMAScript 6 は、2015 年に ECMA によってリリースされた JavaScript 仕様標(biāo)準(zhǔn)です。これは、ES5 に固有の欠點(diǎn)の多くを解決し、モジュール性の考え方を?qū)毪筏皮い蓼埂?ES6 モジュールの設(shè)計(jì)思想は、モジュールの依存関係と入出力変數(shù)をコンパイル時(shí)に決定できるように、可能な限り靜的であることです。
require と import の違い
1、require は実行時(shí)にロードされ、import はコンパイル時(shí)にロードされます。
2、require は次のように実行できます。コードに記述 どの位置でも、import はファイルの先頭にのみ記述でき、條件ステートメントや関數(shù)スコープでは使用できません。
3、module.exports を介して require によってエクスポートされた値は変更できません、インポートはエクスポートを通じてエクスポートされます値は変更できます;
4; require は module.exports を通じてエクスポート オブジェクトをエクスポートし、インポートはエクスポートを通じて出力を指定するコードをエクスポートします;
5, require モジュール屬性は実行時(shí)にのみ導(dǎo)入されるため、パフォーマンスは比較的低くなりますが、インポート コンパイル時(shí)に導(dǎo)入されたモジュールのプロパティはパフォーマンスが若干高くなります。
必須、JavaScript でのインポートおよびエクスポート
理想的には、開(kāi)発者はコア ビジネス ロジックを?qū)g裝するだけで済み、他の開(kāi)発者は他の人が作成したモジュールを読み込むことができます。
ただし、JavaScript はモジュール型プログラミング言語(yǔ)ではなく、es6 より前は「クラス」をサポートしていなかったため、「モジュール」は存在しませんでした。
requireera
JavaScript コミュニティは、既存のオペレーティング環(huán)境で「モジュール」の効果を?qū)g現(xiàn)するために多大な努力を払ってきました。
原文
モジュールとは、特定の機(jī)能を?qū)g裝するメソッドのセットです。
さまざまな関數(shù) (およびステータスを記録する変數(shù)) が単純に組み合わされている限り、それはモジュールとみなされます。
function m1(){ //... } function m2(){ //... }
上記の関數(shù) m1()
と m2()
はモジュールを形成します。使用する場(chǎng)合は直接呼び出してください。
このアプローチの欠點(diǎn)は明らかです。グローバル変數(shù)を「汚染」し、変數(shù)名が他のモジュールと競(jìng)合しないという保証がなく、モジュール メンバー間に直接の関係がありません。
オブジェクトの記述方法
上記の欠點(diǎn)を解決するために、モジュールをオブジェクトとして記述し、すべてのモジュールのメンバーをこのオブジェクト內(nèi)に配置することができます。
var module1 = new Object({ _count : 0, m1 : function (){ //... }, m2 : function (){ //... } });上記の関數(shù)
m1() および
m2() は module1 オブジェクトにカプセル化されています。使用する場(chǎng)合は、このオブジェクトのプロパティを呼び出すだけです。
module1.m1();この書(shū)き方では、すべてのモジュール メンバーが公開(kāi)され、內(nèi)部狀態(tài)を外部から書(shū)き換えることができます。たとえば、外部コードは內(nèi)部カウンターの値を直接変更できます。
module._count = 1;
即時(shí)実行関數(shù)の書(shū)き方
プライベートメンバーを公開(kāi)しないという目的を達(dá)成するには「即時(shí)呼び出し関數(shù)式 IIFE」を使用します
var module = (function() { var _count = 0; var m1 = function() { alert(_count) } var m2 = function() { alert(_count + 1) } return { m1: m1, m2: m2 } })()上記の書(shū)き方では、外部コードから內(nèi)部の_count変數(shù)を読み込むことができません。
console.info(module._count); //undefinedmodule は、JavaScript モジュールを作成する基本的な方法です。
主流のモジュール仕様
es6 より前には、提案された一連の正式な仕様はありませんでしたが、コミュニティとフレームワークの推進(jìn)の観點(diǎn)から、現(xiàn)在はそこにあります。 2 つの一般的な JavaScript モジュール仕様: CommonJS と AMDCommonJS 仕様
2009年,美國(guó)程序員Ryan Dahl創(chuàng)造了node.js項(xiàng)目,將javascript語(yǔ)言用于服務(wù)器端編程。
這標(biāo)志”Javascript模塊化編程”正式誕生。前端的復(fù)雜程度有限,沒(méi)有模塊也是可以的,但是在服務(wù)器端,一定要有模塊,與操作系統(tǒng)和其他應(yīng)用程序互動(dòng),否則根本沒(méi)法編程。
node編程中最重要的思想之一就是模塊,而正是這個(gè)思想,讓JavaScript的大規(guī)模工程成為可能。模塊化編程在js界流行,也是基于此,隨后在瀏覽器端,requirejs和seajs之類(lèi)的工具包也出現(xiàn)了,可以說(shuō)在對(duì)應(yīng)規(guī)范下,require統(tǒng)治了ES6之前的所有模塊化編程,即使現(xiàn)在,在ES6 module被完全實(shí)現(xiàn)之前,還是這樣。
在CommonJS中,暴露模塊使用module.exports
和exports,很多人不明白暴露對(duì)象為什么會(huì)有兩個(gè),后面會(huì)介紹區(qū)別
在CommonJS中,有一個(gè)全局性方法require()
,用于加載模塊。假定有一個(gè)數(shù)學(xué)模塊math.js,就可以像下面這樣加載。
var math = require('math');
然后,就可以調(diào)用模塊提供的方法:
var math = require('math'); math.add(2,3); // 5
正是由于CommonJS 使用的require方式的推動(dòng),才有了后面的AMD、CMD 也采用的require方式來(lái)引用模塊的風(fēng)格
AMD規(guī)范
有了服務(wù)器端模塊以后,很自然地,大家就想要客戶(hù)端模塊。而且最好兩者能夠兼容,一個(gè)模塊不用修改,在服務(wù)器和瀏覽器都可以運(yùn)行。
但是,由于一個(gè)重大的局限,使得CommonJS規(guī)范不適用于瀏覽器環(huán)境。還是上一節(jié)的代碼,如果在瀏覽器中運(yùn)行,會(huì)有一個(gè)很大的問(wèn)題
var math = require('math'); math.add(2, 3);
第二行math.add(2, 3)
,在第一行require(‘math')
之后運(yùn)行,因此必須等math.js加載完成。也就是說(shuō),如果加載時(shí)間很長(zhǎng),整個(gè)應(yīng)用就會(huì)停在那里等。
這對(duì)服務(wù)器端不是一個(gè)問(wèn)題,因?yàn)樗械哪K都存放在本地硬盤(pán),可以同步加載完成,等待時(shí)間就是硬盤(pán)的讀取時(shí)間。但是,對(duì)于瀏覽器,這卻是一個(gè)大問(wèn)題,因?yàn)槟K都放在服務(wù)器端,等待時(shí)間取決于網(wǎng)速的快慢,可能要等很長(zhǎng)時(shí)間,瀏覽器處于”假死”狀態(tài)。
因此,瀏覽器端的模塊,不能采用”同步加載”(synchronous),只能采用”異步加載”(asynchronous)。這就是AMD規(guī)范誕生的背景。
AMD是”Asynchronous Module Definition”的縮寫(xiě),意思就是”異步模塊定義”。它采用異步方式加載模塊,模塊的加載不影響它后面語(yǔ)句的運(yùn)行。所有依賴(lài)這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。
模塊必須采用特定的define()
函數(shù)來(lái)定義。
define(id?, dependencies?, factory)
- id:字符串,模塊名稱(chēng)(可選)
- dependencies: 是我們要載入的依賴(lài)模塊(可選),使用相對(duì)路徑。,注意是數(shù)組格式
- factory: 工廠方法,返回一個(gè)模塊函數(shù)
如果一個(gè)模塊不依賴(lài)其他模塊,那么可以直接定義在define()
函數(shù)之中。
// math.js define(function (){ var add = function (x,y){ return x+y; }; return { add: add }; });
如果這個(gè)模塊還依賴(lài)其他模塊,那么define()
函數(shù)的第一個(gè)參數(shù),必須是一個(gè)數(shù)組,指明該模塊的依賴(lài)性。
define(['Lib'], function(Lib){ function foo(){ Lib.doSomething(); } return { foo : foo }; });
當(dāng)require()
函數(shù)加載上面這個(gè)模塊的時(shí)候,就會(huì)先加載Lib.js文件。
AMD也采用require()
語(yǔ)句加載模塊,但是不同于CommonJS,它要求兩個(gè)參數(shù):
require([module], callback);
第一個(gè)參數(shù)[module],是一個(gè)數(shù)組,里面的成員就是要加載的模塊;第二個(gè)參數(shù)callback,則是加載成功之后的回調(diào)函數(shù)。如果將前面的代碼改寫(xiě)成AMD形式,就是下面這樣:
require(['math'], function (math) { math.add(2, 3); });
math.add()與math模塊加載不是同步的,瀏覽器不會(huì)發(fā)生假死。所以很顯然,AMD比較適合瀏覽器環(huán)境。
目前,主要有兩個(gè)Javascript庫(kù)實(shí)現(xiàn)了AMD規(guī)范:require.js和curl.js。
CMD規(guī)范
CMD (Common Module Definition), 是seajs推崇的規(guī)范,CMD則是依賴(lài)就近,用的時(shí)候再require。它寫(xiě)起來(lái)是這樣的:
define(function(require, exports, module) { var clock = require('clock'); clock.start(); });
CMD與AMD一樣,也是采用特定的define()
函數(shù)來(lái)定義,用require方式來(lái)引用模塊
define(id?, dependencies?, factory)
- id:字符串,模塊名稱(chēng)(可選)
- dependencies: 是我們要載入的依賴(lài)模塊(可選),使用相對(duì)路徑。,注意是數(shù)組格式
- factory: 工廠方法,返回一個(gè)模塊函數(shù)
define('hello', ['jquery'], function(require, exports, module) { // 模塊代碼 });
如果一個(gè)模塊不依賴(lài)其他模塊,那么可以直接定義在define()
函數(shù)之中。
define(function(require, exports, module) { // 模塊代碼 });
注意:帶 id 和 dependencies 參數(shù)的 define 用法不屬于 CMD 規(guī)范,而屬于 Modules/Transport 規(guī)范。
CMD與AMD區(qū)別
AMD和CMD最大的區(qū)別是對(duì)依賴(lài)模塊的執(zhí)行時(shí)機(jī)處理不同,而不是加載的時(shí)機(jī)或者方式不同,二者皆為異步加載模塊。
AMD依賴(lài)前置,js可以方便知道依賴(lài)模塊是誰(shuí),立即加載;
而CMD就近依賴(lài),需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾?lài)了那些模塊,這也是很多人詬病CMD的一點(diǎn),犧牲性能來(lái)帶來(lái)開(kāi)發(fā)的便利性,實(shí)際上解析模塊用的時(shí)間短到可以忽略。
現(xiàn)階段的標(biāo)準(zhǔn)
ES6標(biāo)準(zhǔn)發(fā)布后,module成為標(biāo)準(zhǔn),標(biāo)準(zhǔn)使用是以export指令導(dǎo)出接口,以import引入模塊,但是在我們一貫的node模塊中,我們依然采用的是CommonJS規(guī)范,使用require引入模塊,使用module.exports導(dǎo)出接口。
export導(dǎo)出模塊
export語(yǔ)法聲明用于導(dǎo)出函數(shù)、對(duì)象、指定文件(或模塊)的原始值。
注意:在node中使用的是exports,不要混淆了
export有兩種模塊導(dǎo)出方式:命名式導(dǎo)出(名稱(chēng)導(dǎo)出)和默認(rèn)導(dǎo)出(定義式導(dǎo)出),命名式導(dǎo)出每個(gè)模塊可以多個(gè),而默認(rèn)導(dǎo)出每個(gè)模塊僅一個(gè)。
export { name1, name2, …, nameN }; export { variable1 as name1, variable2 as name2, …, nameN }; export let name1, name2, …, nameN; // also var export let name1 = …, name2 = …, …, nameN; // also var, const export default expression; export default function (…) { … } // also class, function* export default function name1(…) { … } // also class, function* export { name1 as default, … }; export * from …; export { name1, name2, …, nameN } from …; export { import1 as name1, import2 as name2, …, nameN } from …;
- name1… nameN-導(dǎo)出的“標(biāo)識(shí)符”。導(dǎo)出后,可以通過(guò)這個(gè)“標(biāo)識(shí)符”在另一個(gè)模塊中使用import引用
- default-設(shè)置模塊的默認(rèn)導(dǎo)出。設(shè)置后import不通過(guò)“標(biāo)識(shí)符”而直接引用默認(rèn)導(dǎo)入
- -繼承模塊并導(dǎo)出繼承模塊所有的方法和屬性
- as-重命名導(dǎo)出“標(biāo)識(shí)符”
- from-從已經(jīng)存在的模塊、腳本文件…導(dǎo)出
命名式導(dǎo)出
模塊可以通過(guò)export前綴關(guān)鍵詞聲明導(dǎo)出對(duì)象,導(dǎo)出對(duì)象可以是多個(gè)。這些導(dǎo)出對(duì)象用名稱(chēng)進(jìn)行區(qū)分,稱(chēng)之為命名式導(dǎo)出。
export { myFunction }; // 導(dǎo)出一個(gè)已定義的函數(shù) export const foo = Math.sqrt(2); // 導(dǎo)出一個(gè)常量
我們可以使用*和from關(guān)鍵字來(lái)實(shí)現(xiàn)的模塊的繼承:
export * from 'article';
模塊導(dǎo)出時(shí),可以指定模塊的導(dǎo)出成員。導(dǎo)出成員可以認(rèn)為是類(lèi)中的公有對(duì)象,而非導(dǎo)出成員可以認(rèn)為是類(lèi)中的私有對(duì)象:
var name = 'IT筆錄'; var domain = 'http://itbilu.com'; export {name, domain}; // 相當(dāng)于導(dǎo)出 {name:name,domain:domain}
模塊導(dǎo)出時(shí),我們可以使用as關(guān)鍵字對(duì)導(dǎo)出成員進(jìn)行重命名:
var name = 'IT筆錄'; var domain = 'http://itbilu.com'; export {name as siteName, domain};
注意:下面的語(yǔ)法有嚴(yán)重錯(cuò)誤的情況:
// 錯(cuò)誤演示 export 1; // 絕對(duì)不可以 var a = 100; export a;
export在導(dǎo)出接口的時(shí)候,必須與模塊內(nèi)部的變量具有一一對(duì)應(yīng)的關(guān)系。直接導(dǎo)出1沒(méi)有任何意義,也不可能在import的時(shí)候有一個(gè)變量與之對(duì)應(yīng)
export a雖然看上去成立,但是a的值是一個(gè)數(shù)字,根本無(wú)法完成解構(gòu),因此必須寫(xiě)成export {a}的形式。即使a被賦值為一個(gè)function,也是不允許的。而且,大部分風(fēng)格都建議,模塊中最好在末尾用一個(gè)export導(dǎo)出所有的接口,例如:
export {fun as default,a,b,c};
默認(rèn)導(dǎo)出
默認(rèn)導(dǎo)出也被稱(chēng)做定義式導(dǎo)出。命名式導(dǎo)出可以導(dǎo)出多個(gè)值,但在在import引用時(shí),也要使用相同的名稱(chēng)來(lái)引用相應(yīng)的值。而默認(rèn)導(dǎo)出每個(gè)導(dǎo)出只有一個(gè)單一值,這個(gè)輸出可以是一個(gè)函數(shù)、類(lèi)或其它類(lèi)型的值,這樣在模塊import導(dǎo)入時(shí)也會(huì)很容易引用。
export default function() {}; // 可以導(dǎo)出一個(gè)函數(shù) export default class(){}; // 也可以出一個(gè)類(lèi)
命名式導(dǎo)出與默認(rèn)導(dǎo)出
默認(rèn)導(dǎo)出可以理解為另一種形式的命名導(dǎo)出,默認(rèn)導(dǎo)出可以認(rèn)為是使用了default名稱(chēng)的命名導(dǎo)出。
下面兩種導(dǎo)出方式是等價(jià)的:
const D = 123; export default D; export { D as default };
export使用示例
使用名稱(chēng)導(dǎo)出一個(gè)模塊時(shí):
// "my-module.js" 模塊 export function cube(x) { return x * x * x; } const foo = Math.PI + Math.SQRT2; export { foo };
在另一個(gè)模塊(腳本文件)中,我們可以像下面這樣引用:
import { cube, foo } from 'my-module'; console.log(cube(3)); // 27 console.log(foo); // 4.555806215962888
使用默認(rèn)導(dǎo)出一個(gè)模塊時(shí):
// "my-module.js"模塊 export default function (x) { return x * x * x; }
在另一個(gè)模塊(腳本文件)中,我們可以像下面這樣引用,相對(duì)名稱(chēng)導(dǎo)出來(lái)說(shuō)使用更為簡(jiǎn)單:
// 引用 "my-module.js"模塊 import cube from 'my-module'; console.log(cube(3)); // 27
import引入模塊
import語(yǔ)法聲明用于從已導(dǎo)出的模塊、腳本中導(dǎo)入函數(shù)、對(duì)象、指定文件(或模塊)的原始值。
import模塊導(dǎo)入與export模塊導(dǎo)出功能相對(duì)應(yīng),也存在兩種模塊導(dǎo)入方式:命名式導(dǎo)入(名稱(chēng)導(dǎo)入)和默認(rèn)導(dǎo)入(定義式導(dǎo)入)。
import的語(yǔ)法跟require不同,而且import必須放在文件的最開(kāi)始,且前面不允許有其他邏輯代碼,這和其他所有編程語(yǔ)言風(fēng)格一致。
import defaultMember from "module-name"; import * as name from "module-name"; import { member } from "module-name"; import { member as alias } from "module-name"; import { member1 , member2 } from "module-name"; import { member1 , member2 as alias2 , [...] } from "module-name"; import defaultMember, { member [ , [...] ] } from "module-name"; import defaultMember, * as name from "module-name"; import "module-name";
- name-從將要導(dǎo)入模塊中收到的導(dǎo)出值的名稱(chēng)
- member, memberN-從導(dǎo)出模塊,導(dǎo)入指定名稱(chēng)的多個(gè)成員
- defaultMember-從導(dǎo)出模塊,導(dǎo)入默認(rèn)導(dǎo)出成員
- alias, aliasN-別名,對(duì)指定導(dǎo)入成員進(jìn)行的重命名
- module-name-要導(dǎo)入的模塊。是一個(gè)文件名
- as-重命名導(dǎo)入成員名稱(chēng)(“標(biāo)識(shí)符”)
- from-從已經(jīng)存在的模塊、腳本文件等導(dǎo)入
命名式導(dǎo)入
我們可以通過(guò)指定名稱(chēng),就是將這些成員插入到當(dāng)作用域中。導(dǎo)出時(shí),可以導(dǎo)入單個(gè)成員或多個(gè)成員:
注意:花括號(hào)里面的變量與export后面的變量一一對(duì)應(yīng)
import {myMember} from "my-module"; import {foo, bar} from "my-module";
通過(guò)*符號(hào),我們可以導(dǎo)入模塊中的全部屬性和方法。當(dāng)導(dǎo)入模塊全部導(dǎo)出內(nèi)容時(shí),就是將導(dǎo)出模塊('my-module.js')所有的導(dǎo)出綁定內(nèi)容,插入到當(dāng)前模塊('myModule')的作用域中:
import * as myModule from "my-module";
導(dǎo)入模塊對(duì)象時(shí),也可以使用as對(duì)導(dǎo)入成員重命名,以方便在當(dāng)前模塊內(nèi)使用:
import {reallyReallyLongModuleMemberName as shortName} from "my-module";
導(dǎo)入多個(gè)成員時(shí),同樣可以使用別名:
import {reallyReallyLongModuleMemberName as shortName, anotherLongModuleName as short} from "my-module";
導(dǎo)入一個(gè)模塊,但不進(jìn)行任何綁定:
import "my-module";
默認(rèn)導(dǎo)入
在模塊導(dǎo)出時(shí),可能會(huì)存在默認(rèn)導(dǎo)出。同樣的,在導(dǎo)入時(shí)可以使用import指令導(dǎo)出這些默認(rèn)值。
直接導(dǎo)入默認(rèn)值:
import myDefault from "my-module";
也可以在命名空間導(dǎo)入和名稱(chēng)導(dǎo)入中,同時(shí)使用默認(rèn)導(dǎo)入:
import myDefault, * as myModule from "my-module"; // myModule 做為命名空間使用
或
import myDefault, {foo, bar} from "my-module"; // 指定成員導(dǎo)入
import使用示例
// --file.js-- function getJSON(url, callback) { let xhr = new XMLHttpRequest(); xhr.onload = function () { callback(this.responseText) }; xhr.open("GET", url, true); xhr.send(); } export function getUsefulContents(url, callback) { getJSON(url, data => callback(JSON.parse(data))); } // --main.js-- import { getUsefulContents } from "file"; getUsefulContents("http://itbilu.com", data => { doSomethingUseful(data); });
default關(guān)鍵字
// d.js export default function() {} // 等效于: function a() {}; export {a as default};
在import的時(shí)候,可以這樣用:
import a from './d'; // 等效于,或者說(shuō)就是下面這種寫(xiě)法的簡(jiǎn)寫(xiě),是同一個(gè)意思 import {default as a} from './d';
這個(gè)語(yǔ)法糖的好處就是import的時(shí)候,可以省去花括號(hào){}。
簡(jiǎn)單的說(shuō),如果import的時(shí)候,你發(fā)現(xiàn)某個(gè)變量沒(méi)有花括號(hào)括起來(lái)(沒(méi)有*號(hào)),那么你在腦海中應(yīng)該把它還原成有花括號(hào)的as語(yǔ)法。
所以,下面這種寫(xiě)法你也應(yīng)該理解了吧:
import $,{each,map} from 'jquery';
import后面第一個(gè)$是{defalut as $}
的替代寫(xiě)法。
as關(guān)鍵字
as簡(jiǎn)單的說(shuō)就是取一個(gè)別名,export中可以用,import中其實(shí)可以用:
// a.js var a = function() {}; export {a as fun}; // b.js import {fun as a} from './a'; a();
上面這段代碼,export的時(shí)候,對(duì)外提供的接口是fun,它是a.js內(nèi)部a這個(gè)函數(shù)的別名,但是在模塊外面,認(rèn)不到a,只能認(rèn)到fun。
import中的as就很簡(jiǎn)單,就是你在使用模塊里面的方法的時(shí)候,給這個(gè)方法取一個(gè)別名,好在當(dāng)前的文件里面使用。之所以是這樣,是因?yàn)橛械臅r(shí)候不同的兩個(gè)模塊可能通過(guò)相同的接口,比如有一個(gè)c.js也通過(guò)了fun這個(gè)接口:
// c.js export function fun() {};
如果在b.js中同時(shí)使用a和c這兩個(gè)模塊,就必須想辦法解決接口重名的問(wèn)題,as就解決了。
CommonJS中module.exports 與 exports的區(qū)別
Module.exports
The module.exports object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object to module.exports. Note that assigning the desired object to exports will simply rebind the local exports variable, which is probably not what you want to do.
譯文:module.exports對(duì)象是由模塊系統(tǒng)創(chuàng)建的。 有時(shí)這是難以接受的;許多人希望他們的模塊成為某個(gè)類(lèi)的實(shí)例。 為了實(shí)現(xiàn)這個(gè),需要將期望導(dǎo)出的對(duì)象賦值給module.exports。 注意,將期望的對(duì)象賦值給exports會(huì)簡(jiǎn)單地重新綁定到本地exports變量上,這可能不是你想要的。
Module.exports
The exports variable is available within a module's file-level scope, and is assigned the value of module.exports before the module is evaluated. It allows a shortcut, so that module.exports.f = … can be written more succinctly as exports.f = …. However, be aware that like any variable, if a new value is assigned to exports, it is no longer bound to module.exports:
譯文:exports變量是在模塊的文件級(jí)別作用域內(nèi)有效的,它在模塊被執(zhí)行前被賦于 module.exports
的值。它有一個(gè)快捷方式,以便 module.exports.f = …
可以被更簡(jiǎn)潔地寫(xiě)成exports.f = …
。 注意,就像任何變量,如果一個(gè)新的值被賦值給exports,它就不再綁定到module.exports
(其實(shí)是exports.屬性會(huì)自動(dòng)掛載到?jīng)]有命名沖突的module.exports.屬性)
從Api文檔上面的可以看出,從require導(dǎo)入方式去理解,關(guān)鍵有兩個(gè)變量(全局變量module.exports,局部變量exports)、一個(gè)返回值(module.exports)
function require(...) { var module = { exports: {} }; ((module, exports) => { // 你的被引入代碼 Start // var exports = module.exports = {}; (默認(rèn)都有的) function some_func() {}; exports = some_func; // 此時(shí),exports不再掛載到module.exports, // export將導(dǎo)出{}默認(rèn)對(duì)象 module.exports = some_func; // 此時(shí),這個(gè)模塊將導(dǎo)出some_func對(duì)象,覆蓋exports上的some_func // 你的被引入代碼 End })(module, module.exports); // 不管是exports還是module.exports,最后返回的還是module.exports return module.exports; }
demo.js:
console.log(exports); // {} console.log(module.exports); // {} console.log(exports === module.exports); // true console.log(exports == module.exports); // true console.log(module); /** Module { id: '.', exports: {}, parent: null, filename: '/Users/larben/Desktop/demo.js', loaded: false, children: [], paths: [ '/Users/larben/Desktop/node_modules', '/Users/larben/node_modules', '/Users/node_modules', '/node_modules' ] } */
注意
各 js ファイルが作成されると、var exports = module.exports = {}
が作成され、exports と module.exports
の両方が空のオブジェクトを指すようになります。
module.exports
は、exports が指すメモリ アドレスと同じです。
[関連する推奨事項(xiàng): javascript ビデオ チュートリアル 、プログラミングビデオ]
以上がes6 構(gòu)文が必要ですか?の詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國(guó)語(yǔ) Web サイトの他の関連記事を參照してください。

ホットAIツール

Undress AI Tool
脫衣畫(huà)像を無(wú)料で

Undresser.AI Undress
リアルなヌード寫(xiě)真を作成する AI 搭載アプリ

AI Clothes Remover
寫(xiě)真から衣服を削除するオンライン AI ツール。

Clothoff.io
AI衣類(lèi)リムーバー

Video Face Swap
完全無(wú)料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡(jiǎn)単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無(wú)料のコードエディター

SublimeText3 中國(guó)語(yǔ)版
中國(guó)語(yǔ)版、とても使いやすい

ゼンドスタジオ 13.0.1
強(qiáng)力な PHP 統(tǒng)合開(kāi)発環(huán)境

ドリームウィーバー CS6
ビジュアル Web 開(kāi)発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

WebSocketとJavaScript:リアルタイム監(jiān)視システムを?qū)g現(xiàn)するためのキーテクノロジー はじめに: インターネット技術(shù)の急速な発展に伴い、リアルタイム監(jiān)視システムは様々な分野で広く利用されています。リアルタイム監(jiān)視を?qū)g現(xiàn)するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監(jiān)視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実裝原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocket と JavaScript を使用してオンライン音聲認(rèn)識(shí)システムを?qū)g裝する方法 はじめに: 技術(shù)の継続的な発展により、音聲認(rèn)識(shí)技術(shù)は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音聲認(rèn)識(shí)システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音聲認(rèn)識(shí)システムを?qū)g裝する方法を紹介します。

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを?qū)g裝する方法の紹介: インターネットの普及とテクノロジーの進(jìn)歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを?qū)g裝するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム雙方向通信を?qū)g現(xiàn)します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

JavaScript と WebSocket: 効率的なリアルタイム天気予報(bào)システムの構(gòu)築 はじめに: 今日、天気予報(bào)の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報(bào)を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報(bào)システムを構(gòu)築する方法を?qū)Wびます。この記事では、具體的なコード例を通じて実裝プロセスを説明します。私たちは

WebSocket と JavaScript を使用してオンライン予約システムを?qū)g裝する方法 今日のデジタル時(shí)代では、ますます多くの企業(yè)やサービスがオンライン予約機(jī)能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを?qū)g裝することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを?qū)g裝する方法と、具體的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開(kāi)発では、サーバーとのデータ対話(huà)が頻繁に発生します。サーバーと通信するとき、多くの場(chǎng)合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判斷し、さまざまなステータス コードに基づいて対応する処理を?qū)g行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと參照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開(kāi)発では、バックエンド インターフェイスとの対話(huà)を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具體的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開(kāi)始したときに、サービスが
