浅谈模块化(完整版)
===========
原生的JS没有提供模块化,于是有人写了require.js,来帮助JS模块化,有人又不想用第三方提供的JS模块载入框架,所以原生JS的ES6提供了代码的模块化,但是目前大部分的浏览器都不支持ES6的模块化,所以昨天更新了webpack的基本配置,配置完成之后就可以进行ES6模块化的调试了。
也许还有人不知道什么是模块化,给大家举一个简单的例子吧!
我们之前写代码的时候要写的代码很多,有时候可能一个项目里面有的JS代码要用好几遍,如果加载以前的JS代码的话,整个页面就要加载进去,很不利于优化。
JS现在给了我们一个方法,每一个JS文件之间可以互相调用其他的JS的代码,但这个调用不是随意调用,选择把自己的一部分变量,或者函数给别人调用,调用别人的代码的人呢,也要清楚你调用别人的什么函数和变量,就跟去图书馆借书一样,图书馆给你提供你可以借阅的目录,你选择你想看的书籍借阅。
啰嗦了这么多,我们的模块化语法是什么呢?
export var str = 'smallDream'
这就是模块化的抛出语法,听起来有点晦涩对不对, 还是刚刚那个例子,抛出的东西就相当于图书馆的目录,
*export*
是抛出的意思,这句代码的意思是抛出了一个变量名为
*str*
的变量,变量的值为
__'smallDream'__
。
有一点需要注意的地方,所有抛出的变量和函数在外部引用的时候是不可以改变的,就像去图书馆借书,借的时候是什么样子,还的时候还是要一样的,不然是要赔偿的。
上面的一句话就是简单的抛出了一个变量,有抛出就有引用,就像图书馆这时候已经给了你可以借阅的目录,你要怎么借呢?模块化提供了另外的一个方法
import {str} from './one.js'
*import*
是模块化另一个重要的命令,就是引用的意思,上面这句代码的意思是从同级目录的one.js文件中引用了一个
*str*
的变量。你告诉了代码你要去one.js里面
*str*
这个变量,这时候打印str就是上面引用的值了 。
上面只是给大家简单的示范了一下模块化抛出和引用的语法,一次只能抛出一个变量和函数。当我们在项目中真正要用的时候,肯定是有很多需要抛出和引用的函数和变量,当我们遇到大量需要抛出和引用的时候有没有简单一点的写法呢?
export var name = '小梦'
export var age = '18'
export var height = 155;
其实可以简写为
var name = '小梦';
var age = '18';
var height = 165;
export {name age height}
可以在export的后面跟花括号,花括号内抛出多个变量,之后用逗号隔开,输出函数也是一样的
export function f1(str){
return str
}
export function f2(str){
return str
}
export function f3(str){
return str
}
抛出了三个函数,可以简写为
function f1(str){
return str
}
function f2(str){
return str
}
function f3(str){
return str
}
export {f1,f2,f3}
*export*
就这点作用吗?当然不是了,ES6模块化规定了一个关键字
**as**
用于重命名,感动吗?出门前你麻麻还给了你一次可以改名换姓的机会,就像这样
function tiezhu(str){
return str
}
export {tiezhu as Tom}
在家的时候这个函数叫铁柱,出门的时候铁柱麻麻说,儿啊,在外面你可不能被人笑话啊,给你改个洋气点的英文名字Tom吧。于是,出门人家都叫> 你Tom了,铁柱这个名字外面的人再也不知道了。
>总结一下,对外抛出一共有两种方法,第一种方法是export后面声明一个变量抛出,第二种方法是先声明变量,之后export后面跟一个花括号,花括号里面是要抛出的变量和方法。输出的方式一共只有这两种,其他的输出方式都是会直接报错的。
抛出了这么多变量,应该怎么引用呢?
import {f1 as one,f2,f3} from './one.js'
不管抛出多少个,引用方式都是一样的,from的后面可以跟相对路径,也可以跟绝对路径。引用时候的这个花括号是必须要加的。
关键字
*as*
在引用里面一样是生效的。
还有需要注意一点的是const是个块级作用域内的静态变量,整个模块化中应该尽量避免使用const,如果你真的想用的话,ES6也会想办法满足你的。
export const a = 1;
export const b = 2;
export const c = 3;
抛出静态变量的时候引入就要这样写了。
import * from 'one'
这种写法相当于给所有抛出的东西指定了一个对象num,所有抛出的变量和函数都成了这个对象num的方法和属性了。
当抛出的变量和属性很多的时候就可以采用这种方式,调用的时候需要这样写
*.a
它的值就和上一个js中
*const a*
的值是相等的了。
这个方法同样可以用于整体引入,不需要一个一个的把名字列出来,所有抛出的静态变量都被指定在*上面了,可以直接当成对象的属性来调用,堪称懒人福音。
同时这个方法也可以这样用
export var a='小梦姑娘';
export var b='今天北京下雨了';
export var c='我没带伞';
export var all = function(a,b,c){
return a + b + c;
}
上面的这些是需要抛出的变量,引用的时候只需要
import * from './one';
调用函数的时候只需要这样写就可以了
*.all();
但这样写是没有意义的,因为我们还没给函数传参呢
*.all(*.a,*.b,'我刚好带了伞');
这样打印出来的结果应该就是:
小梦姑娘今天北京下雨了我刚好带了伞
如果引用模板少的时候还可以,如果引用模板多了,那么
*
\*
*
之间是会起冲突的,可以换个名字吗?
当然可以了,还记得铁柱出村前改了个名字吗?同样,引入的时候也是允许模块修改自己名字的,语法和抛出时候的语法一样
import * as today from './one'
调用的时候就可以直接用
*today*
来调用了,语法如下:
today.all(today.a,today.b)
是不是比以前一个一个的抛出方便了很多。别急,还有更方便的办法。
export var a = 1;
export var b = 2;
这个JS里面抛出了两个变量,如果在另一个JS里面引用的话可以这样引用
import {a,b} from './one.js';
console.log(a);
console.log(b);
也可以这样引用
import * as num from './one';
console.log(num.a);
console.log(num.b);
可是,如果我不知道a和b的变量名,我们该如何调用呢?
可我们平时工作的时候要处理大量的代码,引用的时候可能不会仔细阅读抛出的变量和方法,这时候我们可能需要一个新的命令
#####
default
这个命令是默认值的意思,他的语法如下
var a = 1;
export default a;
调用的时候语法如下
import default from './one.js';
*default*
实际上是默认的意思,叫什么名字都无所谓,都可以引用到
*a*
这个变量,平时引用的时候都需要用花括号包起来,因为默认值只能有一个,所以引用的时候花括号可以省略。
也可以选择这样引用
import dream from './one';
_dream_
实际就是上个模块中
*a*
的值,默认值是可以和其他的值一起引用抛出的,比如这样
export var a = 'ccc';
export default {
data:{
name:'小梦姑娘',
age:'18'
}
};
引用语法如下
import {_,a} from './one.js';
但是,大部分情况下,我们写模块语法的时候,一般一个模块只抛出一个默认值就够用了,不会选择默认值和其他变量同时抛出,什么?只抛出一个默认值?真的够用吗?兄弟你先别着急
export default {
data:{
name:'张三',
age:18,
family:['爸爸','妈妈','爷爷','奶奶']
},
add:function(a,b){
return a+b;
},
addOne:function(arr){
var nArr = [];
for(let i=0;i<arr.length;i++){
nArr.push(arr[i]+1);
}
}
}
这是一段最简单不过的代码了,只抛出了一个默认值,如何引用相信你一定能想到吧
import myFrist from './one';
let arr = [123,54,'er',54,654,321]
console.log(myFirst.addOne(arr));
这样直接调用就可以了,一般情况下我们都会使用这样的方式调用模块,你也省心,我也省心。
可有的时候,我们可能直接调用不到自己想用的方法,比如你想用的方法在你的同事B定义的模块上,可你和B又没有一点联系,只和同事A有联系,刚好B也和同事A有联系,这时候怎么办呢?
可以让同事A引用B的模块之后抛出,你再引用同事A的模块就好了,听上去好像很简单,可是怎么写呢?
####
我是同事A
import B from './b.js';
export default B ;
直接这样就可以,这样你就可以和同事b没有一点联系,却调用了他的方法,同时同事A这边引用了之后就抛出了,B的代码是不会在A代码部分加载的
每个人都得到了自己想要的东西而且还没有多加载代码,这就是模块化神奇的地方。
同时,模块化是ES6新推出的,并不同于其他代码。
* import后面的from指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。
* import命令具有提升效果,会提升到整个模块的头部,首先执行。
* import是静态执行,所以不能使用表达式和变量,那些是只有在运行时才能得到结果的语法结构。
比如
if(a === 1){
import one from './one.js';
}//报错,不被允许的写法
>关于模块化的语法平时用到的大概也只有这些了,当然,模块化的内容还有好多,我能做的,只是把我知道的分享给大家。
>如果想要更深刻的了解模块化,还是需要多实践和参考官网的内容。
>如果您发现本文有错误的地方欢迎您与我联系。