转载请注明预见才能遇见的博客:http://my.csdn.net/
原文地址:http://blog.csdn.net/pcaxb/article/details/53670097
// ES6模块
import { stat, exists, readFile } from 'fs';
上面代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。由于 ES6 模块是编译时加载,使得静态分析成为可能。有了它,就能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。除了静态加载带来的各种好处,ES6 模块还有以下好处://方式一
export let name = '张三';
//方式二(推荐)可以一起在模块结束位置输出
let age = 12;
let height = 14;
//导出多个数据,单个数据也一样。
export {age,height};
//export age;或者export 12;都是错误的写法
//方式三(输出函数)
//1
export let reduce1 = function reduce1(){
console.log('reduce1函数减少');
};
export let add1 = ()=>{
console.log('add1函数增加');
};
//2
let reduce2 = function reduce2(){
console.log('reduce2函数减少');
};
export {reduce2};
function reduce2k(){
console.log('reduce2k函数减少');
};
export {reduce2k};
let add2 = ()=>{
console.log('add2函数增加');
};
export {add2};
//3
export function reduce3(){
console.log('reduce3函数减少');
};
//export function(){} 没有函数名,不能这么写
//export ()=>{} 没有函数名,不能这么写
//export add3(){} 不能这样写
//方式四(类)
可以使用as关键字,重命名函数或者变量等,重命名后可以用不同的名字export多次输出export {
age as AGE1,
age as AGE2,
height as HEIGHT
};
另外,export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。这一点与CommonJS规范完全不同,CommonJS模块输出的是值的缓存,不存在动态更新。export var foo = 'bar';
setTimeout(()=>{foo = 'baz';},500)
import {name} from './Modules';
console.log(name);
import {age,height} from './Modules';
console.log(age + "===" + height);
import {reduce1,reduce2,reduce2k,reduce3,add1,add2} from './Modules';
reduce1();
reduce2();
reduce2k();
reduce3();
add1();
add2();
import {foo} from './Modules';
console.log(foo);
setTimeout(()=>{console.log(foo)},500);
import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块对外接口的名称相同。可以使用as关键字,重命名函数或者变量等,重命名后可以用不同的名字import多次输入import {name as name1,name as name2} from './Modules';
console.log(name1+"==="+name2);
export和import命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错。这是因为处于条件代码块之中,就没法做静态优化了,违背了ES6模块的设计初衷。//导出多个数据,单个数据也一样。
export {age,height};
//方式二(推荐)可以一起在模块结束位置输出
let age = 12;
let height = 14;
export放到函数里面输出就会报错function A(){
//导出多个数据,单个数据也一样。
export {age,height};
}
//SyntaxError: 'import' and 'export' may only appear at the top level
import也是同理://正确
console.log(name);
import {name} from './Modules';
//错误
function A(){
import {name} from './Modules';
}
export和import命令是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。// 报错
import { 'f' + 'oo' } from 'my_module';
// 报错
let module = 'my_module';
import { foo } from module;
// 报错
if (x === 1) {
import { foo } from 'module1';
} else {
import { foo } from 'module2';
}
import语句会执行所加载的模块,因此可以有下面的写法,如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。import './Modules';
//错误import * from './Modules';
上面代码仅仅执行Modules模块,但是不输入任何值, 比如在某个模块中做了一些不需要输入值的操作,就可以使用,下面是使用import导入样式文件:import './style.css';//import导入样式
当然样式文件也可以使用一下方式使用样式
import styles from './xx.css';
className="直接的样式名字"和className={styles.root},这里的className可以直接写样式的名字,也可以使用导入的名字点css的样式名字。//模块的整体加载
import * as Modules from './Modules';
console.log(Modules);
console.log("模块的整体加载"+Modules.age + "=="+Modules.name);
export default class Person {
getAge() {
console.log('Person age');
}
};
let weight = 100;
export default weight;
let width = 30;
export {width as default};
export default命令只能使用一次,如果同一个文件中使用了多个export default,前面的将会被覆盖,但是使用export符合用法时,重复会报错。其他模块加载该模块时,import命令可以为该匿名函数指定任意名字,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面,不使用大括号。import data from './Modules';
console.log(data+"===");
export default命令用在非匿名函数前,也是可以的。下面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载。export default function foo() {
console.log('foo');
}
//或者写成
function foo() {
console.log('foo');
}
export default foo;
本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。function add(x, y) {
return x * y;
}
//export
export {add as default};
// 等同于
// export default add;
//import
import { default as xxx } from 'modules';
// 等同于
// import xxx from 'modules';
正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。// 正确
export var a = 1;
// 正确
var a = 1;
export default a;
// 错误
export default var a = 1;
如果想在一条import语句中,同时输入默认方法和其他变量,可以写成下面这样import _,* as Modules1 from './Modules';
console.log(_);
console.log(Modules1);
或者
import _, { name,age } from './Modules';
如果要输出默认的值,只需将值跟在export default之后即可export default 12;
//输出
export {name,age} from './Modules';
// 等同于
import {name,age} from './Modules';
export {name,age};
//输入
import {name,age} from './Tab';
console.log(name + "Q"+age);
模块的接口改名和整体输出,也可以采用这种写法
//输出
export {name as firstName} from './Modules';
//输入
import {firstName} from './Tab';
console.log(firstName+"===============");
整体输出//输出
export * from './Modules';
//输入
import {name,age} from './Tab';
console.log(name + "Q"+age);
//或者
import * as Tab from './Tab';
console.log(Tab.name + "XXX" + Tab.age);
说明:整体输出和部分输出不能同时使用,这里的整体不包括默认。//输出
export {default} from './Modules';
//输入
import TabDef from './Tab';
console.log(TabDef);
说明:如果需要输出默认和整体,可以同时使用默认和整体两条输出命令。export {height as default} from './Modules';
// 等同于
import { height } from './Modules';
export default height;
同样地,默认接口也可以改名为具名接口。//输入
export {default as defWidth} from './Modules';
//输出
import {defWidth} from './Tab';
console.log(defWidth);
//TabParent.js
export let w = 1;
export let h = 2;
//Tab.js
export * from './TabParent';//Tab继承TabParent
//TabMain.js
import {w,h} from './Tab';
console.log(w+"======="+h);
//输入Tab.js
let count = 1;
function compute(){
count++;
}
module.exports = {
count:count,
compute:compute
};
//输出TabMain.js
let TabES5 = require('./Tab');
console.log(TabES5.count);//1
TabES5.compute();
console.log(TabES5.count);//1
上面代码说明,Tab.js模块加载以后,它的内部变化就影响不到输出的TabES5.count了。这是因为TabES5.count是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。let count = 1;
function compute(){
count++;
}
module.exports = {
get count() {
return count
},
compute:compute
};
ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值。因此,ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。//输入Tab.js
let count = 1;
function compute(){
count++;
}
export {count,compute}
//输出TabMain.js
import {count,compute} from './Tab';
console.log(count);//1
compute();
console.log(count);//2
由于ES6输入的模块变量,只生成一个动态的只读引用,所以这个变量是只读的,对它进行重新赋值会报错,只能改变对象属性的值,不能够改变引用。如果是一个基本数据类型,不是引用类型的数据,也不能改变他的值。//输入Tab.js
export let obj = {};
//输出TabMain.js
import {obj} from './Tab';
obj.len = 10;
console.log(obj);
//obj = {len:20};SyntaxError: "obj" is read-only
说明:如果在Tab.js中obj是10,在TabMain.js中也不能改变obj=20。