1. 用模块封装代码
模块:自动运行在严格模式下并且没有办法退出运行的JavaScript代码
注:1)在模块顶部创建的变量不会自动被添加到全局共享作用域;这个变量仅在模块的顶级作用域中存在,
模块必须导出外部代码可以访问的元素,如:变量或函数是(模块可以从其他模块导入绑定)
2)模块间的特性与作用域关系不大,但很重要
1.模块顶部,this的值是undefined;
2.模块不支持html风格的代码注释(早期浏览器残余下来的js特性);
脚本?模块?
脚本 == 任何非模块的js代码
2. 导出的基本语法?
export关键字作用:将代码暴露给其他模块
{
可以将export放在任何变量、函数或类声明的前面(从模块导出)
}
// 导出数据(变量)
export var color= "red"
export let name = "dachengz"
export const farmNum = 77
// 导出函数 此方式属于导出声明
export function sum(num1, num2){
return num1 + num2;
}
// 导出类
export class Rectangle {
constructor(length, width) {
this.length = length
this.width = width
}
}
// 函数是模块私有的
function subtract(num3, num4){
return num3 - num4
}
// 定义一个函数- 外部无法访问(属于模块的私有方法)
function multiple(a,b) {
return a * b
}
// ...将它导出 此方式属于导出引用
export multiple
3. 导入的基本语法
import 语句两个部分分别是: 要导入的标识符和标识符应当从哪个模块导入
import { A, B} from './example.js'
{} : 从给定模块导入的绑定(binding)
关键字from : 表示从哪个模块导入给定的绑定(该模块由表示模块路径的字符串指定)被称作模块的说明符
1.导入单个绑定
import {sum} from './example.js'
console.log(sum(1,2)) // 3
sum =1 // 抛出一个错误 不能给导入的绑定重新赋值
注意:为了兼容多个浏览器和Node.js环境, 一定要在字符串之前包含 / 、./ 、或 ../ 来表示要导入的文件
2. 导入多个绑定
导入3个绑定
import {sum, multiple, farmNum} from './example.js'
console.log(sum(1,farmNum)) // 78
console.log(multiple(1,2)) // 2
3.导入整个模块
特殊情况下,可导入整个模块作为一个单一的对象。然后所有的导出都可以作为对象的属性使用
// 导入一切 命名空间导入
import * as example from './example.js'
console.log(example.sum(1,example.farmNum)) // 78
console.log(example.multiple(1,2)) // 2
从example.js中导出的所有绑定被加载到一个被称作example的对象中;
注意: 模块语法的限制
{
export、import它们必须在其它语句和函数之外使用。
}
4.导入绑定的一个微妙怪异之处
es6中Import语句为变量、函数和类创建的是只读绑定,而不是像正常变量一样简单地引用原始绑定
标识符只有在被导出的模块中可以修改,即便是导入绑定的模块也无法更改绑定的值
export var name = 'dcz'
export function setName(newName) {
name = newName
}
当导入这两个绑定后,setName()函数可以改变name的值
import {name, setName} from './example.js'
console.log(name) // dcz
setName('hehe')
console.log(name) // hehe
name = 'dcz' // 抛出错误
调用setName('Grep') 时会回到导出setName()的模块中去执行,并将name设置为'Grep'。
注意:此处的更改会自动在导入的name绑定上体现出来。因为,name是导出的name 标识符的本地名称。
5.导出和导入时重命名
起因:从其他模块导入类、函数、变量等时,不想使用原始名称。我们可以再导出过程和导入过程中改变元素的名称
例如使用不同的名称导出一个函数,使用as关键字来指定函数在模块外被叫做什么名字
导出时:
/*example.js中如下代码*/
function format(a,b) {
return a + b
}
export { format as sum}
注意:format()是本地函数;sum()是我们导出时使用的名字。
如果其他模块要导入这个函数是,必须使用sum这个名字: import { sum } from '../example.js'
再举例子2:utils工具类下一个单独文件url.js;统一管理在index.js中
export default {
getQueryStringByName(name){
// todo ....
},
route2Page(vm, destRoutePath, queryParams, replace) {
// todo...
},
routeBypassNPage(vm, n) {
// todo
}
}
此时,默认导出的是一个对象;而在index.js中配置
export { default as url } from './url' // 默认导出名字就是url
之所以这么写,为了我们后续在导入时,直接引入utils即可(其实是默认读取index.js文件而已),
导入时:
import {} from 'utils' // 同理 import {} from 'utils/index.js'
import { url } from 'utils' 即我们可以再后续使用url中的函数
例如:url.getQueryStringByName(...) url.route2Page(...), ...等
注意:我们也可以在导入时,重新指定导入名字,使用as关键字
import { url as urlUtil } from 'utils' // 后续操作是一样的 urlUtil.getQueryStringByName(...) ...,
6.模块的默认值
模块的默认值指的是通过default关键字指定的单个变量、函数、或类
(注意:只能为每个模块设置一个默认的导出值)多次使用default关键字是一个语法错误
上述描述中已经涉及到默认导出,default
接下来,我们再具体看看其他的demo
export default function (num1, num2){
return num1 + num2
}
模块导出一个函数作为它的默认值
同理,可以再export default之后添加默认导出值的标识符
function sum(a1,a2){ return a1 * a2}
export default sum
6.导入默认值
// 导入默认值
import sum from './example.js'
console.log(sum(2,2)) // 4
export let color = 'blue'
export default function(num1,num2){
return num1 + num2
}
// 可用import 导入color 和默认函数
import sum, {color} from './example.js' // 使用逗号将默认的本地名称与大括号包裹的非默认值分开
注意:在import语句中,默认值必须排在非默认值之前
console.log(sum(1,2)) // 3
console.log(color) // 'blue'
重新导出一个绑定怎么做?
无绑定的导入又是什么?(应用于创建polyfill和shim)
我们思考下应用场景。。。