看过很多片段讲解es6的module功能,import、export、export default用起来还是一知半解。
关键词:运行时加载、编译时加载
最开始写的js
到处都是全局变量和方法,容易重名。
// index.js
var attr1 = '全局变量1';
var attr2 = '全局变量2';
function fn1() {};
function fn2() {};
命名空间方式
为了避免重名问题衍生,命名空间的模式,全局暴露一个对象把方法和属性存在这个对象里面。
var scopeObj = {
attr: '变量',
fn(){console.log('yes!')},
}
console.log(scopeObj.attr); // 变量
scopeObj.fn(); // yes!
// 不安全,被直接修改属性和方法
scopeObj.attr = '我被修改了'
scopeObj.fn = function () {
console.log('no!')
}
console.log(scopeObj.attr); // 我被修改了
scopeObj.fn(); // no!
IIFE 函数自执行方式
(function(win){
function fn1() {
console.log('方法1')
}
function fn2() {
console.log('方法2')
}
win.fns = {fn1, fn2}
// 可调用
fns.fn1(); // 方法1
// 覆盖方法,单不能修改原有定义
fns.fn1 = function () {
console.log('方法3');
}
win.fns2 = {fn1, fn2}
fns.fn1(); // 方法3
// 照常输入
fns2.fn1(); // 方法1
})(window)
// 依赖第三方插件情况,讲究引入先后顺序功能复杂理不清依赖先后顺序
// 引用交叉问题:假设c.js依赖b.js, b.js依赖a.js, 没有把a.js加上就导致了引用报undefined错误
(function(win, $){
function fn() {
var app = $('#app')
}
win.myFuns = {fn}
})(window, jQuery)
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 函数自执行模式 -->
<script src="./a.js"></script>
<script src="./b.js"></script>
<script src="./c.js"></script>
</head>
<body>
</body>
</html>
// a.js
// b.js
// c.js
AMD\CMD\UMD\CommonJS\ES Modules
CommonJS
module.export、require
// 导出
function sayNo(){console.log('no!')}
function sayHello(){console.log('hi!')}
module.export = {
sayNo: sayNo,
sayHello: sayHello
}
// 导入
const say = require('./hello.js')
say.sayNo()
AMD (require.js)
define、require
// 模块定义
define(function(){
return {name: 'miki'}
})
// 模块依赖其他模块, 第一个参数为依赖模块数组方式
define(['jquery'], function($){
return {name: 'miki'}
})
// 引用模块
require(['jquery', 'monent'], function($, monent){
var app = $('#app')
})
CMD (sea.js)
define、exports、seajs.use
// 模块定义
define(function(require, exports, module){
var $ = require('jquery')
var say = function(){console.log('hello world!')}
exports.say = say
})
// 模块引用
// 这个使用方式和AMD的模块引用差别在关键字?
seajs.use(['say.js'], function(sayFn){
sayFn.say()
})
ES6 Module
export、export default、import
// 必须配对关系方法或者值必须放在变量里
var a = '1'
var b = functon(){}
export {
a: a,
b: b
}
// 使用
import {a, b} from './test.js'
// 使用export default导出的模块使用可以省略花括号
export default {a, b}
import test from './test.js'
// 为import模块重新命名(防止两个模块中命名冲突)
import test as test1 from './test.js'
import {a as a1, b as b1} from './test.js'
疑问
// 脑壳疼为啥会有后面的default嘛
const x = require('xx').default