在上一篇文章中JavaScript中AMD和ES6模塊的導入導出對比,偏向於理論層面,還有一些同窗在微信羣裏或是私下裏針對一些問題進行了溝通,因此有了這一篇文章,對js的導入導出進行總結和實踐javascript
這個問題其實已經和導入導出沒什麼關係了, 咱們看一個知乎上的問題(詳細地址閱讀原文能夠查看) 咱們以此爲突破點 js 數組賦值問題 :值傳遞仍是引用?前端
var a = [1,2,3];
var b = a;
a = [4,5,6];
console.log(b); //=>[1,2,3]
複製代碼
繼續看java
var a = [1,2,3];
var b = a;
a.pop();
console.log(b); //=>[1,2]
複製代碼
爲何會出現這種狀況?es6
數組和對象的賦值操做都是引用傳遞數組
看下這個(留意註釋部分)微信
var a = [1,2,3];// a指向了數組 [1,2,3];
var b = a;//b 指向 a 所指向的數組[1,2,3];
a = [4,5,6];//a 指向了新的數組 [4,5,6],(a的指向發生了變化,改變的是a引用自己,沒有改變數組對象,因此b沒有變)
console.log(b); //b沒有改變,仍是指向數組 [1,2,3];
複製代碼
再看下這個(留意註釋部分)函數
var a = [1,2,3];// a指向了數組 [1,2,3];
var b = a;//b 指向 a 所指向的數組[1,2,3];
a.pop();// a 指向的數組實例發生了 pop 操做
console.log(b); //=>a和b都是指向同一個數組,a變量,因此b也變量,最後輸出=>[1,2]
複製代碼
var test = {
"name": "zhangshuo"
}
var demo = test;
demo.name = "want you"
//你認爲test是什麼?
console.log(test)//=>{ name: 'want you' }
複製代碼
下面經過註釋解釋一下(一模一樣)spa
var test = { "name": "zhangshuo"}//test指向了一個對象 { "name": "zhangshuo"}
var demo = test;//demo 指向 test 所指向的對象 { "name": "zhangshuo"}
demo.name = "want you"//對象的屬性發生了改變 { "name": "want you"}
//你認爲test是什麼?
console.log(test)//=>{ name: 'want you' }
複製代碼
test和demo指向了同一個對象,一個變了,就都變了 一樣的,咱們對上面的demo作一下改造code
var test = {
"name": "zhangshuo"
}
var demo = test;
test={
"name": "更改了這個name"
}
demo.name = "want you"
//你認爲test是什麼?
console.log(test)//=>{ name: '更改了這個name' }
複製代碼
還須要對此進行贅述嗎? 仍是經過註釋對此進行解釋說明
var test = { "name": "zhangshuo"}//test指向了一個對象 { "name": "zhangshuo"}
var demo = test;//demo 指向 test 所指向的對象 { "name": "zhangshuo"}
test={ "name": "更改了這個name" }//test的指向發生了變化,指向了一個新對象{ "name": "更改了這個name" }
demo.name = "want you"//demo的指向沒有變,改變了原對象的屬性 { "name": "want you"}
//你認爲test是什麼?
console.log(test)//=>{ name: '更改了這個name' }
複製代碼
我相信,上面的兩個栗子你已經看懂了,即將進入正題 先來一個過渡 再看一個栗子,用來模擬exports和 module.exports的關聯關係
let md = {exps:{}}//md指向一個對象 {exps:{}}
let exps = md.exps//exps指向了md.exps所指向的對象 ,這個空對象{}
md.exps = {a: 1, b: 2}//md.exps指向了一個新對象 {a: 1, b: 2}
exps.c=3//exps,屬性賦值 {c: 3}
console.log(md.exps); //新對象{ a: 1, b: 2 }
複製代碼
上面栗子中的md就是module,md.exps就是module.exports,exps就是exports 在每個模塊的頭部都有一行這樣的命令
var exports = module.exports;
複製代碼
當直接給module.exports賦值時(module.exports={.....}),module.exports就指向了一個新對象,exports會失效
仍是這樣的一個前提
var exports = module.exports;
複製代碼
exports是來自於module,exports指向 module.exports所指向的對象 當直接給exports賦值,即
exports = {a:1}
複製代碼
exports指向了一個新對象,再也不是 module.exports所指向的對象,因此不要給 exports 直接賦值( exports =。。。)
exports的output.js
exports.str='string字符串'//導出字符串
exports.bool=true//導出布爾
exports.num=123//導出number
exports.foo=(r)=>{//導出函數
console.log(`導出函數爲:${r}`);
}
exports.arr=[1,2,3]//導出數組
exports.obj={ a:1, b:2}//導出對象
複製代碼
input.js
const iptObj= require('./output.js')
console.log(iptObj.str);//=>string字符串
console.log(iptObj.bool);//=>true
console.log(iptObj.num);//=>123
console.log(iptObj.arr);//=>[ 1, 2, 3 ]
console.log(iptObj.obj);//=>{ a: 1, b: 2 }
iptObj.foo('參數')//=>導出函數爲:參數
複製代碼
module.exports的output.js
module.exports={
str:'string字符串',
bool:true,
num:123,
foo:(r)=>{
console.log(`導出函數爲:${r}`);
},
arr:[1,2,3],
obj:{ a:1, b:2}
}
複製代碼
input.js
const iptObj= require('./output.js')
console.log(iptObj.str);//=>string字符串
console.log(iptObj.bool);//=>true
console.log(iptObj.num);//=>123
console.log(iptObj.arr);//=>[ 1, 2, 3 ]
console.log(iptObj.obj);//=>{ a: 1, b: 2 }
iptObj.foo('參數')//=>導出函數爲:參數
複製代碼
module.exports的output.js同時支持以下寫法
module.exports.str='string字符串'
module.exports.bool=true
module.exports.num=123
module.exports.foo=(r)=>{
console.log(`導出函數爲:${r}`);
}
module.exports.arr=[1,2,3]
module.exports.obj={ a:1, b:2}
複製代碼
input.js不變
export的output.js
export const srt = 'string字符串'
export const bool = true
export const num = 123
export const arr = [1, 2, 3]
export const obj = { a: 1, b: 2}
export function foo(r) {
console.log(`導出函數爲:${r}`);
}
複製代碼
input.js
import {str,arr,obj,bool,num,foo} from './output'
console.log(str)
console.log(arr)
console.log(obj)
console.log(bool)
console.log(num)
foo('參數')
複製代碼
export的output.js同時支持以下寫法
const str = 'string字符串'
const bool = true
const num = 123
const arr = [1, 2, 3]
const obj = { a: 1, b: 2}
function foo(r) {
console.log(`導出函數爲:${r}`);
}
export {
str,bool,num,arr,obj,foo
}
複製代碼
input.js 導入支持重命名
import {str as STR,arr,obj,bool,num,foo as FOO} from './output'
console.log(STR)
console.log(arr)
console.log(obj)
console.log(bool)
console.log(num)
FOO('參數')
複製代碼
繼續重命名
import * as newName from './output'
console.log(newName.str)
console.log(newName.arr)
console.log(newName.obj)
console.log(newName.bool)
console.log(newName.num)
newName.foo('參數')
複製代碼
export default的output.js
export default {
str: 'string字符串',
bool: true,
num: 123,
foo: (r) => {
console.log(`導出函數爲:${r}`);
},
arr: [1, 2, 3],
obj: { a: 1, b: 2 }
}
複製代碼
input.js
import defaultObj from './output'
console.log(defaultObj.str)
console.log(defaultObj.arr)
console.log(defaultObj.bool)
console.log(defaultObj.num)
console.log(defaultObj.obj)
defaultObj.foo('ef')//=>導出函數爲:ef
複製代碼
export default的output.js同時支持以下寫法
const str = 'string字符串'
const bool = true
const num = 123
const arr = [1, 2, 3]
const obj = {a: 1, b: 2}
function foo(r) {
console.log(`導出函數爲:${r}`);
}
export default {
str,
bool,
num,
arr,
obj,
foo
}
複製代碼
input.js不變
這篇文章是對上一篇文章的總結和實踐
更多前端資源請關注微信公衆號「前端陌上寒」
參考連接