es6 自动采用严格模式 ,不管在模块头上加上“ use strict ”
严格模式限制
1.变量必须声明后使用
2.禁止this指向全局对象
3.不能使用 with 语句
4.函数的参数不能有同名属性,否则报错
5.不能对制度属性赋值,否则报错。
6.不能使用 0 前缀表示八进制数,否则报错。
9.不能删除不可删除属性,否则报错。
es6 模块中中,顶层 的this 指向 undefined ,既不应该在顶层的代码中使用this。
export 命令
模块功能主要有两个命令构成: export 和 import。export 命令用于规定模块对外的接口,import 命令用于输入其他模块提供的功能。
一个模块就是一个独立的文件,改文件内部所有的变量。外部无法获取。如果希望外部能够读取模块内部某个变量,就必须使用 export 关键字输出该变量。
eg: 使用 export 输出3个变量
export var firstName = 'tom';
export var lastName = 'jerry';
export var yesr = '1956';
还可以这样写
var firstName = 'tom';
var lastName = 'jerry';
var yesr = '1956';
输出变量
export { firstName,lastName,year } ;
推荐使用后一种,前后两种方法等价。但后一种放在脚本尾部比较直观看出输出那些变量。
export 除了输出变量还可以输出函数或类(class);
export function multiply (x,y){
return x*y;
}
上面的代码对外输出一个函数 multiply 。
一般情况下 export 输出的变量就是本来的名字,但可以使用 as 关键字命名。
function v1 (){........}
function v2 (){.........}
export {
v1 as streamV1,
v2 as streamV2 ,
v2 as streamlast
}
使用 as 关键字重命名后,v2 可以用不同的名字输出两次。
export 命令规定的是对外的接口,必须与模块内部的变量建立一一对应的关系。
//错误示例
export 1;
var f = 1;
export f;
//正确示例
export var m = 1;
var f = 1;
export { f} ;
export 命令可以出现在模块的任何位置,只要处于模块的 顶层就可以。如果处于块级作用于内,就会报错 。 import 命令也一样。
import 命令
使用 export 命令定义模块对外的接口后,其他 js 就可以通过 使用 import 命令加载这个模块了。
import { firstName,lastName,year } from './profile'
function setName(element){
element.textContext = firstName + ' ' + lastName;
}
上面的 import 命令用于加载 profile.js文件,并输入变量。import 命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号的变量名必须与被导入模块(profile.js)对外接口的名称相同。
如果想为输入的变量重新取一个名字,要在 import 命令中使用 as 关键字,将输入的变量重命名。
import { lastName as surName} from './profile.js';
import 后面的 from 指模块文件的位置。可以是相对路径,也可以是绝对路径 ,.js可以省略。如果只是模块名,不指定路径,那么必须有配置文件告诉 JavaScript 引擎该模块的位置。
import 命令具有提升效果 ,会提升到整个模块的头部首先执行。
foo();
import { foo } from './my_module';//代码并不会报错
由于 import 是静态执行,所以不能使用表达式和变量,只有在运行时才能得到结果的语法结构。
//错误
1. import { 'f' + 'oo' } from './my_module' ;
2. let module = 'my_module';
import { foo } from module;
3. if(x == 1){
import { foo } from 'module1';
}else {
import { foo } from 'module2';
}
import 是单利模式,重复执行统一语句时 ,只会执行一次
eg: import 'loadsh';
import 'loadsh';
import { foo } from '/loadsh';
import { bar } from '/loadsh';
以上语句都只执行一次。
模块的整体加载
除了指定加载某个输出值,还可以使用整体加载(即 * ) 来指定一个对象,所有输出都加载在这个对象上。
// circle.js
export function area ( redus ){
return Math.PI*radius*radius;
};
export function circumference( redus ){
return 2*Math.PI*radius;
}
加载模块 (逐一加载)
import { area ,circumference } from '/circle' ;
console.log("圆的面积: "+ area(4));
console.log("圆的周长: "+circumference(4));
整体加载
import * as circle from '/circle' ;
console.log("圆的面积: "+ circle.area(4));
console.log("圆的周长: "+circle.circumference(4));
模块整体加载所在的对象(上例是 circle ) 应该是可以静态分析的,所以不允许运行时改变。
import * as circle from ''/circle';
//下面操作不允许
circle.foo = ' hello';
circle.area = function () { } ;