avaScript 程序不能獨(dú)立運(yùn)行,它需要被嵌入 HTML 中,然后瀏覽器才能執(zhí)行 JavaScript 代碼。通過 <script> 標(biāo)簽將 JavaScript 代碼引入到 HTML 中,有兩種方式:
1.內(nèi)部方式
內(nèi)部方式是通過<script>標(biāo)簽包裹JavaScript代碼,從而引入HTML頁面中,示例代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript 基礎(chǔ) - 引入方式</title>
</head>
<body>
<!-- 內(nèi)聯(lián)形式:通過 script 標(biāo)簽包裹 JavaScript 代碼 -->
<script>
alert('嗨,歡迎來傳智播學(xué)習(xí)前端技術(shù)!')
</script>
</body>
</html>
2.外部形式
一般將 JavaScript 代碼寫在獨(dú)立的以 .js 結(jié)尾的文件中,然后通過 <script>標(biāo)簽的 <src>屬性引入,示例代碼如下:
// demo.js
document.write('嗨,歡迎來傳智播學(xué)習(xí)前端技術(shù)!')
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript 基礎(chǔ) - 引入方式</title>
</head>
<body>
<!-- 外部形式:通過 script 的 src 屬性引入獨(dú)立的 .js 文件 -->
<script src="demo.js"></script>
</body>
</html>
注意:如果 script 標(biāo)簽使用 src 屬性引入了某 .js 文件,那么 標(biāo)簽的代碼會(huì)被忽略!!!如下代碼所示:
網(wǎng)頁中編寫JavaScript代碼時(shí),需要先引入JavaScript代碼。JavaScript代碼有3種引入方式,分別是行內(nèi)式、嵌入式和外鏈?zhǔn)剑旅娣謩e進(jìn)行講解。
行內(nèi)式是將JavaScript代碼作為HTML標(biāo)簽的屬性值使用。例如,在單擊超鏈接“test”時(shí),彈出一個(gè)警告框提示“Hello”,示例代碼如下:
<a href="javascript:alert('Hello');">test</a>
需要說明的是,行內(nèi)式只有在臨時(shí)測試或者特殊情況下使用,一般情況下不推薦使用行內(nèi)式,因?yàn)樾袃?nèi)式有如下缺點(diǎn)。
(1)行內(nèi)式可讀性較差,尤其是在HTML文件中編寫大量JavaScript代碼時(shí),不方便閱讀。
(2)行內(nèi)式在遇到多層引號嵌套的情況時(shí),引號非常容易混淆,導(dǎo)致代碼出錯(cuò)。
嵌入式(或稱內(nèi)嵌式)使用<scrip>標(biāo)簽包裹JavaScript代碼,直接編寫到HTML文件中,通常將其放到<head>標(biāo)簽<body>或標(biāo)簽中。<scrip>標(biāo)簽的type屬性用于告知瀏覽器腳本類型,HTML.5中該屬性的默認(rèn)值為“text/javascript”,因此在使用HTML5時(shí)可以省略ype屬性。嵌入式的示例代碼如下:
<script>
JavaScript代碼
</script>
外鏈?zhǔn)?或稱外部式)是將JavaScript 代碼寫在一個(gè)單獨(dú)的文件中,一般使用“js”作為文件的擴(kuò)展名,在HTML頁面中使用<script>標(biāo)簽的src屬性引人“js”文件。外鏈?zhǔn)竭m合javascript代碼量較多的情況。在html頁面中引入“js”文件,示例代碼如下:
<script src="test.js"></script>
上述代碼表示引入當(dāng)前目錄下的tesL.js文件。需要注意的是,外鏈?zhǔn)降臉?biāo)簽內(nèi)不可以編寫JavaScript 代碼。
為了幫助初學(xué)者更好地理解外鏈?zhǔn)剑旅胬猛怄準(zhǔn)綄?shí)現(xiàn)瀏覽網(wǎng)頁時(shí)在頁面中自動(dòng)彈出警告框。創(chuàng)建Example02.html文件,引入Example02.js文件,具體代碼如例1-2所示。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="Example02.js"></script>
</body>
</html>
標(biāo)簽的src屬性設(shè)置了要引入的文件為Example02.js。
創(chuàng)建Example02.js文件,在該文件中編寫如下代碼:
alert ('Hello JavaScript');
保存代碼,在瀏覽器中訪問Example02.html文件,頁面效果與例1-1相同。
以上講解了JavaScript的3種引入方式。現(xiàn)代網(wǎng)頁開發(fā)中提倡結(jié)構(gòu)、樣式、行為的分離,即分離HTML、CSS、JavaScrixt這3部分代碼,這樣更有利于文件的維護(hù)。當(dāng)需要編寫大量的、邏輯復(fù)雜的、具有特定功能的JavaScrigt代碼時(shí),推薦使用外鏈?zhǔn)健M怄準(zhǔn)较啾惹度胧剑哂幸韵?點(diǎn)優(yōu)勢:
(1)外鏈?zhǔn)酱嬖谟讵?dú)立文件中,有利于修改和維護(hù),而嵌人式會(huì)導(dǎo)致HTML代碼與JavaScript代碼混合在一起。
(2)外鏈?zhǔn)娇梢岳脼g覽器緩存提高速度。例如,在多個(gè)頁面中引入相同的JavaScript文件時(shí),打開第1個(gè)頁面后,瀏覽器將JavaScript文件緩存下來,下次打開其他頁面時(shí)就不用重新下載該文件了。
(3)外鏈?zhǔn)接欣贖TML頁h代碼結(jié)構(gòu)化,把大段的JavaScript代碼分離到HTML頁面之外,既美觀,也方便文件級別的代碼復(fù)用。
著現(xiàn)代 Web 開發(fā),我們要么使用 require 要么使用 import 引用 JavaScript 依賴項(xiàng)。有時(shí),我們將兩者結(jié)合使用。
但是,你知道為什么這兩者都存在嗎? 使用一種或另一種時(shí)的最佳實(shí)踐是什么?
在本文中,我將討論使用 require 和 import 并回答其中一些常見問題。
在討論 require 和 import 之前,有必要對 JavaScript 模塊有一定的了解。 那么,讓我們看看有哪些不同類型的 JavaScript 模塊可用。
引入了 AMD 模塊以使模塊更加前端友好。 它們不需要任何打包器,并且所有依賴項(xiàng)都是動(dòng)態(tài)解析的。
AMD使用 require 函數(shù)用于加載外部模塊,并且能夠充當(dāng) CommonJS 模塊的包裝器。
define("exampleModule", [], () => {
return {
print: () => console.log("Hello World!");
}
}
define("main", ["require", "exampleModule"], (require) => {
const exampleModule= require("exampleModule");
exampleModule.print();
});
但是,隨著 ES 模塊的引入,AMD 的使用量急劇減少。
CommonJS 是 NodeJS 用來在模塊中封裝 JavaScript 的標(biāo)準(zhǔn)。 module.exports用于導(dǎo)出 CommonJS 模塊,以及 import 函數(shù)用于將模塊包含到單獨(dú)的文件中。
盡管 CommonJS 模塊在 NodeJS 中被廣泛使用,但在前端開發(fā)中并沒有使用它們。 這背后的主要原因是require函數(shù)的同步行為。
但是,NodeJS 從 v13 開始才開始支持 ES 模塊。 在那之前,大多數(shù) NodeJS 模塊,包括 NPM 庫,都是使用 CommonJS 模塊開發(fā)的。
因此,CommonJS 模塊仍然在開發(fā)人員中廣泛使用。
而且,CommonJS 模塊與 ES 模塊同樣重要,我將在本文接下來的部分中討論更多。
UMD 是 AMD 和 CommonJS 的組合。 它使用了 AMD 的 CommonJS 語法和異步加載技術(shù),使其適用于服務(wù)器端和客戶端。
UMD 在 Webpack 等打包器中用作回退模塊,下面顯示了一個(gè)簡單的 UMD 模塊示例:
(function (root, factory) {
if (typeof define === "function" && define.amd) {
define(["jquery"], factory); // AMD } else if (typeof exports === "object" ) { module.exports = factory(require("jquery")); //CommonJS } else { root.returnExports = factory(root.jQuery); }
})(this, function ($) {
function exampleFunction() {}
return exampleFunction;
});
ES Modules (ECMAScript Modules) 是 JavaScript 中使用的官方標(biāo)準(zhǔn)。 ES 模塊使用 import和 export 處理模塊的語句。 它解決了 CommonJS 的最大限制之一,即同步加載。
在引入 ES Modules 之后,開發(fā)者之間有很多爭論,考慮到與 CommonJS 的兼容性。 但是,開發(fā)人員已經(jīng)適應(yīng)使用這兩種方法,我們將在接下來的部分中討論更多詳細(xì)信息。
已經(jīng)了解了 JavaScript 模塊的背景,那么讓我們繼續(xù)討論 require 和 import.
require通常與 NodeJS 一起使用來讀取和執(zhí)行 CommonJS 模塊。
這些模塊可以是內(nèi)置模塊,如 http或自定義編寫的模塊。 使用 require,可以將它們包含在 JavaScript 文件中并使用它們的函數(shù)和變量。
// 內(nèi)置模塊
const http= require('http');
// 本地模塊
const getBlogName = require('./blogDetails.js')
但是,如果要使用 require 要獲取本地模塊,首先需要使用 module.exports 導(dǎo)出它們.
例如,假設(shè)您有一個(gè)名為 blogDetails.js,并且您需要使用該文件中的函數(shù) index.js文件。
// blogDetails.js
const getBlogTitle = (name, author) => {
return name + " by " + author;
}
modules.export = getBlogTitle;
// index.js
const getBlogTitle = require('./blogDetails.js');
var title = getBlogTitle ('Require vs Import in JavaScript', 'Chameera Dulanga');
還可以使用一次導(dǎo)出多個(gè)模塊 modules.export 如下:
const getBlogTitle = (name, author) => {
return name + " by " + author;
}
const getBlogContent = () => {
return content
}
modules.export = {
getBlogTitle,
getBlogContent,
};
注意: 如果最后不是使用 modules.export,可以附加 exports 。 例如: exports.getBlogContent = () => {};
我想現(xiàn)在你明白什么時(shí)候應(yīng)該使用 require以及它是如何工作的。 接下來讓我們看看如何 import 。 然后我們將能夠以更深層次的理解來比較和對比它們。
import 是一個(gè) ES 模塊,并帶有 export,它們被稱為 ES6 import 和 export.
我們不能用 import 或?qū)С龅?ES 模塊之外。
試圖 import ES 模塊之外是一個(gè)常見的開發(fā)人員錯(cuò)誤。
如果我舉同樣的例子,我需要做的唯一改變就是修改 modules.export到 export default.
const getBlogTitle = (name, author) => {
return name + " by " + author;
}
export default getBlogTitle;
然后我們可以使用 import 將此文件包含在我們的 index.js文件。
import getBlogTitle from "./blogDetails.js";
var title = getBlogTitle ('Require vs Import in JavaScript', 'Chameera Dulanga');
注意: 類似于 require,還可以通過將導(dǎo)出附加到每個(gè)函數(shù)定義來單獨(dú)導(dǎo)出每個(gè)函數(shù)。
例如: export const = getBlogContent = () => {};
所以,我想你現(xiàn)在明白應(yīng)該如何以及何時(shí)使用 require和 import。但是,這還不是全部; 它們的功能和用法存在一些顯著差異。 是時(shí)候進(jìn)行比較了。
require 和 import 都用于包含模塊。 但是它們有幾個(gè)應(yīng)該注意的重要功能。
import 語句只能在文件的開頭定義。 定義一個(gè) import 其他地方的語句會(huì)給你一個(gè)錯(cuò)誤或自動(dòng)轉(zhuǎn)移到文件的開頭。
聲明 require 時(shí),當(dāng)加載的模塊名稱未預(yù)定義時(shí),允許有條件地或動(dòng)態(tài)地加載模塊。
例如,你可以調(diào)用 require 在函數(shù)或 if 條件中,如下所示:
if(articleCount>0){
const getBlogTitle = require(‘./blogDetails.js’);
}
require語句具有這種靈活性,因?yàn)樗鼈儽灰暈楹瘮?shù)。 它們在運(yùn)行時(shí)被調(diào)用,在此之前沒有辦法知道任何事情。 但, import 語句是靜態(tài)的,我們不能有條件地或動(dòng)態(tài)地使用它們。
注意: 由于 import 語句是靜態(tài)的,所以可以在運(yùn)行應(yīng)用程序之前檢測到任何錯(cuò)誤
在小型應(yīng)用程序中,同步或異步可能不會(huì)發(fā)揮主要作用。 但是,如果我們考慮大型應(yīng)用程序,則會(huì)使用數(shù)百個(gè)模塊。 所以,如果你使用 require, 模塊將被一 一加載和處理。
而 import 語句通過異步工作解決了這個(gè)問題,這比 require 在大規(guī)模應(yīng)用中更能發(fā)揮作用。
正如我們所討論的,ES 模塊系統(tǒng)是作為維護(hù)客戶端 JavaScript 模塊的標(biāo)準(zhǔn)引入的。 TypeScript 也采用了它,并添加了用于定義 Type 的內(nèi)容。 因此,我不認(rèn)為 require可以再次取代 ES,因?yàn)樗殉蔀殚_發(fā)人員中廣泛使用的標(biāo)準(zhǔn)。
但是由于有大量的 NodeJS 模塊和庫是用 CommonJS 編寫的,我們不能保留 require完全放在一邊。 所以我們必須相應(yīng)地使用它們。
如果你使用的是 TypeScript,則可以通過配置 tsconfig.json文件。 例如,假設(shè)我們需要輸出一個(gè)使用 CommonJS 的代碼版本。
需要做的就是創(chuàng)建一個(gè)新的 tsconfig 通過擴(kuò)展原始文件用于 CommonJS 輸出 tsconfig文件并修改 module下參數(shù) CompilerOptions.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"outDir": "./lib/cjs"
},
}
注意: 還可以使用 Webpack 等構(gòu)建工具將 ES 模塊轉(zhuǎn)換為 CommonJS 模塊。
以下表格為比較兩者
特征 | require | import |
語法 | const x=require() | import x from './' |
模塊 | CommonJS | ES |
異步 | 不支持 | 支持 |
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。