模塊化編程 1.基本介紹 傳統的非模塊化開發有如下的缺點:(1)命名衝突(2)文件依賴 JavaScript代碼越來越龐大,JavaScript引入模塊化編程,開發者只需要實現核心的業務邏輯,其他都可以載入別人已經寫好的模塊 JavaScript使用“模塊”(module)的概念來實現模塊化編程,解 ...
模塊化編程
1.基本介紹
- 傳統的非模塊化開發有如下的缺點:(1)命名衝突(2)文件依賴
- JavaScript代碼越來越龐大,JavaScript引入模塊化編程,開發者只需要實現核心的業務邏輯,其他都可以載入別人已經寫好的模塊
- JavaScript使用“模塊”(module)的概念來實現模塊化編程,解決非模塊化編程問題。
- 模塊化也是ES6新特性
2.模塊化編程原理示意圖
3.模塊化編程的分類
- CommonJS模塊化規範/ES5的寫法
- ES6模塊化規範
3.1CommonJS模塊化規範/ES5的寫法
3.1.1介紹
- 每個js文件就是一個模塊,有自己的作用域。在文件中定義的變數、函數、類/對象,都是私有的,對其他js文件不可見
- CommonJS使用
module.exports={}
或者exports={}
導出模塊,使用let/const 名稱=require("xx.js")
導入模塊
3.1.2應用實例
-
需求說明
- 編寫function.js,該文件有函數,變數,常量,對象,數組....
- 要求在use.js,可以使用到function.js中定義的函數/變數/常量/對象
- 請用模塊化編程的方式完成,儘量將各種寫法都寫一下
-
思路分析
-
代碼應用
function.js
//定義一些對象,變數,常量,函數等 const sum = function (a, b) { return parseInt(a) + parseInt(b); } const sub = function (a, b) { return parseInt(a) - parseInt(b); } let name = "jack"; const PI = 3.14; const monster = { name: "牛魔王", age: 500, hi() { console.log("hi 你好,牛魔王"); } } //導出 /** * 1.module.exports 導出模塊 * 2.把你需要導出的數據,寫入到{}中即可 * 3.可以全部導出,也可以部分導出 * 4.理解:相當於把所有導出的數據當做一個對象 * 5.如果屬性名和屬性值(即要導出的函數/變數/對象...)的名字相同,可以簡寫 * 6.module.exports ={} 也可以簡寫為 exports= {} */ exports = { //簡寫 sum, sub, name, PI } // module.exports = { //完整的寫法--屬性:屬性值 // sum: sum, // sub: sub, // myname: name, // PI: PI // }
use.js
//導入 /** * 1.在es5中,通過require 把對應文件.js 中的數據/對象 引入 * 2.通過 對象.屬性 的形式使用 * 3.如果我們導入時,不需要所有的數據,可以導入部分數據 */ const m = require("./function.js"); const {sub} = require("./function.js"); //使用 console.log(m.sub("100", "200")); console.log(m.sum(10, 90)); console.log(m.name); console.log(m.PI); console.log(sub(19, 3));
3.2ES6模塊化規範
3.2.1介紹
-
ES6使用
(1)
export{對象/函數/變數/常量等}
(批量導出)(2)
export 定義 = {}
(定義導出)(3)
export default {}
(預設導出)以上三種方式都可導出模塊
-
如果使用的是批量導出或定義導出的,導入時要用
import {} from "xx.js"
形式如果用預設導出的,導入時要用
import 名稱 from "xx.js"
形式
3.2.2應用實例-批量導出形式
-
需求說明
- 編寫common.js,該文件有函數,變數,常量,對象
- 要求在use_common.js中,可以使用到common.js中定義的 函數/變數/常量/對象
- 請使用ES6模塊化編程的方式完成
-
代碼實現
common.js
//定義一些對象,變數,常量,函數等 const sum = function (a, b) { return parseInt(a) + parseInt(b); } const sub = function (a, b) { return parseInt(a) - parseInt(b); } let name = "jack"; const PI = 3.14; const monster = { name: "牛魔王", age: 500, hi() { console.log("hi 你好,牛魔王"); } } /** * es6之批量導出 * 1.export 就是導出模塊/數據 * 2.可以全部導出,也可以部分導出 */ export { sum, sub, name, monster }
use_common.js
/** * 導入 * 1.可以使用{} 來接收導出的數據 * 2.可以全部接收,也可以選擇的接收 * 3.細節:導入{}中的名字,要求和導出{}中的名稱一致 */ import {monster, name} from "./common.js"; //使用 console.log(monster); console.log(name);
3.2.3應用實例-其他導出形式
- 定義導出
common2.js
//定義一些對象,變數,常量,函數等
//定義導出
//定義sum函數時,就直接導出
//如果在定義時導出的數據,在導入時要保持名稱一致
export const sum = function (a, b) {
return parseInt(a) + parseInt(b);
}
use_common2.js
//可以導入模塊/數據
import {sum} from "./common2.js";
//使用
console.log(sum(10, 40));
- 預設導出
common3.js
//定義一些對象,變數,常量,函數等
//演示預設導出
//可以這樣理解,類似於把{}內的數據當做一個對象導出
export default {
sum(a, b) {
return parseInt(a) + parseInt(b);
},
sub(a, b) {
return parseInt(a) - parseInt(b);
}
}
use_common3.js
//導入預設導出的模塊/數據
//m的名稱是可以自定義的,因此就可以解決命名衝突的問題
import m from "./common3.js";
//以 對象.屬性 的形式使用
console.log(m.sum(11, 22));
console.log(m.sub(88, 66));
3.2.4註意事項和細節
- ES6的模塊化無法在Node.js中執行,需要用Babel轉碼ES5後再執行
- export不僅可以導出對象,一切JS變數都可以導出。比如:基本類型變數,函數,數組,對象
- 沒有導出的數據不能使用
- ES6的導出方式有很多,不同的導出方式對導入方式也有影響
4.練習
-
請編寫一個文件hw_common.js,該文件有對象cat(屬性有name,age,cry() ),對象dog(屬性有name,age,hi() )
- 使用批量導出
- 使用定義導出
- 使用預設導出
hw_common.js
(1)批量導出:
const cat = { name: "貓貓", age: 2, cry() { console.log("喵喵"); } } const dog = { name: "狗狗", age: 3, hi() { console.log("旺旺"); } } //批量導出 export {cat,dog}
(2)定義導出
export const cat = { name: "貓貓", age: 2, cry() { console.log("喵喵"); } } export const dog = { name: "狗狗", age: 3, hi() { console.log("旺旺"); } }
(3)預設導出
//預設導出 //註意寫法有一些變化,把我們的兩個對象當做{}的屬性即可 export default { cat: { name: "貓貓", age: 2, cry() { console.log("喵喵"); } }, dog: { name: "狗狗", age: 3, hi() { console.log("旺旺"); } } }
-
編寫use_common.js,在該文件中使用hw_common.js導出的模塊/數據,註意體會使用特點
導入預設導出的數據:
//導入預設導出的數據 import m from "./hw_common.js"; //使用 console.log(m.cat.name, m.cat.age, m.cat.cry()); console.log(m.dog.name, m.dog.age, m.dog.hi());
導入 批量導出或定義導出 的數據:
//導入 批量導出或定義導出 的數據 import {dog, cat} from "./hw_common.js"; //使用 console.log(dog.name,dog.hi()); console.log(cat.name,cat.cry());
-
a.js有一個dog對象(含有hi()方法),b.js也有一個dog對象(含有say()方法),請使用模塊化的編程思路,在a.js能使用到不同的dog對象,請編程完成。
使用預設導出解決命名衝突
b.js
//預設導出 export default { dog: { say() { console.log("say...") } } }
a.js
const dog = { hi() { console.log("hi..") } } //導入預設導出的數據 import dog2 from "./b.js"; //使用 console.log(dog2.dog.say(), dog.hi());