1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

docs(class): export 输出的是同一个实例

This commit is contained in:
ruanyf 2016-03-27 11:07:29 +08:00
parent 8796fc605f
commit 8c4187a2f7

View File

@ -73,9 +73,9 @@ export var lastName = 'Jackson';
export var year = 1958;
```
上面代码是`profile.js`文件保存了用户信息。ES6将其视为一个模块里面用export命令对外部输出了三个变量。
上面代码是`profile.js`文件保存了用户信息。ES6将其视为一个模块里面用`export`命令对外部输出了三个变量。
export的写法除了像上面这样还有另外一种。
`export`的写法,除了像上面这样,还有另外一种。
```javascript
// profile.js
@ -86,7 +86,7 @@ var year = 1958;
export {firstName, lastName, year};
```
上面代码在`export`命令后面使用大括号指定所要输出的一组变量。它与前一种写法直接放置在var语句前是等价的但是应该优先考虑使用这种写法。因为这样就可以在脚本尾部一眼看清楚输出了哪些变量。
上面代码在`export`命令后面,使用大括号指定所要输出的一组变量。它与前一种写法(直接放置在`var`语句前)是等价的,但是应该优先考虑使用这种写法。因为这样就可以在脚本尾部,一眼看清楚输出了哪些变量。
export命令除了输出变量还可以输出函数或类class
@ -113,6 +113,60 @@ export {
上面代码使用`as`关键字,重命名了函数`v1``v2`的对外接口。重命名后,`v2`可以用不同的名字输出两次。
需要特别注意的是,`export`命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
```javascript
// 报错
export 1;
// 报错
var m = 1;
export m;
```
上面两种写法都会报错因为没有提供对外的接口。第一种写法直接输出1第二种写法通过变量`m`还是直接输出1。`1`只是一个值,不是接口。正确的写法是下面这样。
```javascript
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m};
// 写法三
var n = 1;
export {n as m};
```
上面三种写法都是正确的,规定了对外的接口`m`。其他脚本可以通过这个接口,取到值`1`。它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系。
同样的,`function``class`的输出,也必须遵守这样的写法。
```javascript
// 报错
function f() {}
export f;
// 正确
export function f() {};
// 正确
function f() {}
export {f};
```
另外,`export`语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
```javascript
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
```
上面代码输出变量`foo`,值为`bar`500毫秒之后变成`baz`
这一点与CommonJS规范完全不同。CommonJS模块输出的是值的缓存不存在动态更新详见下文《ES6模块加载的实质》一节。
最后,`export`命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下一节的`import`命令也是如此。这是因为处于条件代码块之中就没法做静态优化了违背了ES6模块的设计初衷。
```javascript
@ -124,15 +178,6 @@ foo()
上面代码中,`export`语句放在函数之中,结果报错。
`export`语句输出的值是动态绑定,绑定其所在的模块。
```javascript
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
```
上面代码输出变量`foo`,值为`bar`500毫秒之后变成`baz`
## import命令
使用`export`命令定义了模块的对外接口以后其他JS文件就可以通过`import`命令加载这个模块(文件)。
@ -365,7 +410,7 @@ let o = new MyClass();
模块之间也可以继承。
假设有一个`circleplus`块,继承了`circle`模块。
假设有一个`circleplus`块,继承了`circle`模块。
```javascript
// circleplus.js
@ -515,6 +560,48 @@ obj = {}; // TypeError
上面代码中,`main.js``lib.js`输入变量`obj`,可以对`obj`添加属性,但是重新赋值就会报错。因为变量`obj`指向的地址是只读的,不能重新赋值,这就好比`main.js`创造了一个名为`obj`的const变量。
最后,`export`通过接口,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例。
```javascript
// mod.js
function C() {
this.sum = 0;
this.add = function () {
this.sum += 1;
};
this.show = function () {
console.log(this.sum);
}
}
export let c = new C();
```
上面的脚本`mod.js`,输出的是一个`C`的实例。不同的脚本加载这个模块,得到的都是同一个实例。
```javascript
// x.js
import {c} from './mod';
c.add();
// y.js
import {c} from './mod';
c.show();
// main.js
import './x';
import './y';
```
现在执行`main.js`输出的是1。
```bash
$ babel-node main.js
1
```
这就证明了`x.js``y.js`加载的都是`C`的同一个实例。
## 循环加载
“循环加载”circular dependency指的是`a`脚本的执行依赖`b`脚本,而`b`脚本的执行又依赖`a`脚本。