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)) // 3sum =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) // hehename = '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)我们思考下应用场景。。。