---恢复内容开始---
1.概述
ES6中模块的设计思想:尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入输出的变量。
import {stat,exists,readFile} from 'fs';
2.严格模式
--
变量必须声明后再使用
函数的参数不能有同名属性
不能使用with语句
不能对只读属性赋值
不能使用前缀0表示八进制数
不能删除不可删除的属性
不能删除变量dalete prop,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
eval和arguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用argument.callee
不能使用argument.caller
禁止this指向全局对象
不能使用fn.caller和fn.arguments获取函数调用的堆栈
增加了保留字(如protected、static和interface)
ES6中顶层的this指向undefined,因此不应该在顶层代码使用this
3.export命令
必须使用export关键字输出模块内部的变量后,外部才能读取
//profile.js export var firstName = 'Micheal'; export var lastName = 'jackson'; export var year = 1958;
另一种写法
//profile.js var firstName = 'michael'; var lastName = 'jackson'; var year = 1958; export {firstName,lastName,year};
在export命令后面使用大括号指定所要输出的一组变量。可以一眼看出输出了那些函数或类
export除了输出变量还可以输出函数或类
export function multiply(x,y){ return x * y; };
export输出的变量就是本来的名字,但是可以使用as重命名
function v1(){ ... } function v2(){ ... } export{ v1 as streamV1, v2 as streamV2, v2 as streamLatestVersion }
重命名后,V2可以用不同的名字输出两次
注意:export命令规定的是对外的接口,必须与模块内部的变量建立一一对应的关系
如果输出的不是接口而是一个值得话会报错
//写法1 export var m = 1; //写法2 var m = 1; export {m}; //写法3 var n = 1; export {n as m};
上面三种写法都是正确的,规定了对外的接口m
。其他脚本可以通过这个接口,取到值1
。它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系。
function和calss的输出,也必须遵循这样的写法
//错误 function f(){} export f; //正取 export function f(){}; //正确 function f(){} export {f};
要么export 后面直接跟函数,要么export后面使用{函数名}
export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口可以取到模块内部实时的值
export var foo = 'bar'; setTimeout(() => foo = 'baz', 500);
CommonJs模块输出的是值得缓存,不存在动态更新。
export命令可以处于模块任何位置,只要处于模块顶层就可以。不能放在块作用域中
放在块作用域中就没法做静态优化,违背ES6模块设计初衷。
function foo(){ export default 'bar' //SyntaxError } foo()
import命令
import命令用于加载模块。大括号里的变量名必须与被导入模块对外接口一致。
重命名:使用as关键字重命名
import {lastName as surname} from './profile';
如果只是模块名,不带有路径,那么必须有配置文件,告诉js引擎该模块的位置
import {myMethod} from 'util';
不带路径必须要有配置文件
import命令具有提升效果,会提升到整个模块的头部首先执行
foo();
import { foo } from 'my_module';
提升的本质:import命令是编译阶段执行的,在代码运行之前。
由于import是静态执行,所以不能使用表达式和变量
//报错 import {'f' + 'oo'} from 'my_module'; //报错 let module = 'my_module'; import { foo } from module; //报错 if( x === 1){ import { foo } from 'module1'; import { foo } from 'module2'; }
在静态分析阶段,表达式都是无法得到值的。
import会执行所加载的模块
import 'loadsh';
以上仅仅执行loadsh模块,但是不输入任何值
多次重复同一import语句,那也只会执行一次,不会执行多次
import { foo } from 'my_module'; import { bar } from 'my_module'; //等同于 import { foo, bar} from 'my_module';
import语句是Singleton(单实例)模式
CommonJS模块的require命令和import命令最好别写在同一模块中,因为import会首先执行
模块的整体加载
用( * )指定一个对象,所有的输出值都加载在这个对象上
import * as circle from './circle';
模块整体加载所在的那个对象,不允许运行时改变。
import * as circle from './circle'; //下面两行代码不允许 circle.foo = 'hello' circle.area = function (){}
export default命令
export default为模块指定默认输出
//export-default.js export default function(){ console.log('foo'); }
其它模块加载export default命令导出的模块时,import命令可以为该匿名函数指定任意名字
//import-default.js import customName from './export-deault'; customName(); //'foo'
注意:这时import命令后面不使用大括号
export default命令也可以用在非匿名函数前
export default function foo(){ console.log('foo'); } //另一种写法 function foo(){ console.log('foo'); } export default foo;
上面代码中,foo
函数的函数名foo
,在模块外部是无效的。加载的时候,视同匿名函数加载
本质上,export default
就是输出一个叫做default
的变量或方法,然后系统允许你为它取任意名字。
export default命令后面不能跟变量声明语句
---恢复内容结束---