导入绑定的一个微妙怪异之处:import 为变量、函数、类创建的是只读绑定,而不是像正常变量一样简单地引用原始绑定。
// 模块(x.js) export let name = 'ph' export function setName(newName){ name = newName } // 模块(y.js) import {name, setName} from './x.js' // ph console.log(name) // 此更改会自动在导入的 name 绑定上体现 // 原因是 name 是导出的 name 标识符的本地名称 setName('lj') // lj console.log(name) // webpack 中没有抛出错误 name = 3 // 3 console.log(name) 导出和导入时重命名如果要使用不同的名字导入一个函数,可以使用 as 关键字,代码示意如下:
// 解构导出并重命名 export const { age, sum: add } = o; import {sum as add} from './x.js'; import {default as DefaultExport} from './x.js' 模块的默认值模块的默认值指的是通过 default 关键字指定的单个变量、函数或类。就像这样:
export default function(v1, v2){ return v1 + v2 }只能为每个模块设置一个默认的导出值:
// 语法错误 export default 1 export default 2如果想通过一条语句同时指定多个导出,包括默认导出,下面这个语法非常有用:
const age = 18 function sum(v1, v2){ return v1 + v2 } export {sum as default, age}可以通过一条语句导入所有导出的绑定,包括默认值:
import sum, {age} from './x.js'用逗号将默认的本地名称与大括号包裹的非默认值分割开。默认值必须排在非默认值前面:
// 报错 import {age}, sum from './x.js'与导出默认值一样,也可以在导入默认值时使用重命名语法:
import {default as sum, age} from './x.js'这段代码中,默认值被重命名为 sum,并且还导入了 age。
重新导出一个绑定在一个模块中导入 sum,又重新导出 sum,就像这样:
import {sum} from './x.js' export {sum}只用一条语句同样可以完成上面的工作:
export {sum} from './x.js'这种形式的 export 在指定的模块中查找 sum 声明,然后将其导出。理解了这个语法后,我们在这种形式下,可以重命名或者导出一切。就像这样:
// 重命名导出 export {sum as add} from './x.js' // 导出一切 export * from './x.js'注:测试发现此语法(export * from './x.js')没有导出默认值
无绑定导入有些模块可能不导出任何东西。可能只修改全局作用域中的对象。
虽然模块中顶层的变量、函数和类不会自动出现在全局作用域中,但这并不意味着模块无法访问全局作用域,比如我在某模块中给数组添加一个变量,其他模块没有引入该模块,也是可以访问到数组新添加的变量,请看示例:
// x.js Array.prototype.myFlag = 'aaron' // y.js console.log(Array.prototype.myFlag) // index.js // 由于不导出任何东西,因此可以使用简化的导入操作 import './x.js' // 模块 y 输出:aaron import './y.js'Tip: 无绑定导入最有可能用于 polyfill 和 shim
综合测试我们将上文介绍的知识点综合测试和验证一下。
入口文件(src/index.js):
// 无绑定导入 import './a.js' // 重复导入。只会输出一次”i am moduleC“ import './c.js' import './c.js' import './d.js'其他文件内容如下:
a.js:
// 用逗号将默认的本地名称与大括号包裹的非默认值分割开。默认值必须排在非默认值前面 import multiplication, {name,age,sum,address,tel,Dog,SEX,HOUSE} from './b.js' // console.table,将数据以表格的形式显示 console.table({ // name 和 age:导出数据 name, age, // 导出函数 'sum(3,3)': sum(3, 3), // address 和 tel:一次导出多个 address, tel, "new Dog('乐乐', '黑色', 4)": new Dog('乐乐', '黑色', 4).toString(), // 默认导出 'multiplication(3, 3)': multiplication(3, 3), // 重命名导出 SEX, // 解构导出 HOUSE })b.js:
// 导出数据 export var name = 'ph' export let age = 18 const sex = 'man' // 解构导出 export const { house: HOUSE} = {house:'别墅'} // 一次导出多个 export let address='长沙', tel='123456789' // 导出函数 export function sum(v1, v2){ return v1 + v2 } // 导出类 class Dog{ constructor(name, color, age){ this.name = name; this.color = color; this.age = age; } toString(){ return `name=${this.name} color=${this.color} age=${this.age}` } } // 这个函数是模块私有的 function subtract(v1, v2){ return v1 - v2; } // 定义一个函数 function multiplication(v1, v2){ return v1 * v2 } // 导出模块集合 export {Dog} // 重命名导出 export {sex as SEX} // 默认导出 export default multiplication // 报错 // export multiplication