Skip to content

Commit 4c8c37c

Browse files
committed
docs(module): edit SystemJS
1 parent 4fb1525 commit 4c8c37c

File tree

2 files changed

+82
-15
lines changed

2 files changed

+82
-15
lines changed

docs/class.md

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,16 +285,26 @@ p3.printName() // "Oops"
285285

286286
上面代码在`p1`的原型上添加了一个`printName`方法,由于`p1`的原型就是`p2`的原型,因此`p2`也可以调用这个方法。而且,此后新建的实例`p3`也可以调用这个方法。这意味着,使用实例的`__proto__`属性改写原型,必须相当谨慎,不推荐使用,因为这会改变Class的原始定义,影响到所有实例。
287287

288-
### name属性
288+
### 不存在变量提升
289289

290-
由于本质上,ES6的Class只是ES5的构造函数的一层包装,所以函数的许多特性都被Class继承,包括`name`属性
290+
Class不存在变量提升(hoist),这一点与ES5完全不同
291291

292292
```javascript
293-
class Point {}
294-
Point.name // "Point"
293+
new Foo(); // ReferenceError
294+
class Foo {}
295295
```
296296

297-
`name`属性总是返回紧跟在`class`关键字后面的类名。
297+
上面代码中,`Foo`类使用在前,定义在后,这样会报错,因为ES6不会把变量声明提升到代码头部。这种规定的原因与下文要提到的继承有关,必须保证子类在父类之后定义。
298+
299+
```javascript
300+
{
301+
let Foo = class {};
302+
class Bar extends Foo {
303+
}
304+
}
305+
```
306+
307+
上面的代码不会报错,因为`class`继承`Foo`的时候,`Foo`已经有定义了。但是,如果存在Class的提升,上面代码就会报错,因为`class`会被提升到代码头部,而`let`命令是不提升的,所以导致`class`继承`Foo`的时候,`Foo`还没有定义。
298308

299309
### Class表达式
300310

@@ -342,33 +352,90 @@ person.sayName(); // "张三"
342352

343353
上面代码中,person是一个立即执行的Class的实例。
344354

345-
### 不存在变量提升
355+
### 私有方法
346356

347-
Class不存在变量提升(hoist),这一点与ES5完全不同。
357+
私有方法是常见需求,但ES6不提供,只能通过变通方法模拟实现。
358+
359+
一种做法是在命名上加以区别。
348360

349361
```javascript
350-
new Foo(); // ReferenceError
351-
class Foo {}
362+
class Widget {
363+
364+
// 公有方法
365+
foo (baz) {
366+
this._bar(baz);
367+
}
368+
369+
// 私有方法
370+
_bar(baz) {
371+
return this.snaf = baz;
372+
}
373+
374+
// ...
375+
}
352376
```
353377

354-
上面代码中,`Foo`类使用在前,定义在后,这样会报错,因为ES6不会把变量声明提升到代码头部。这种规定的原因与下文要提到的继承有关,必须保证子类在父类之后定义。
378+
上面代码中,`_bar`方法前面的下划线,表示这是一个只限于内部使用的私有方法。但是,这种命名是不保险的,在类的外部,还是可以调用到这个方法。
379+
380+
另一种方法就是索性将私有方法移出模块,因为模块内部的所有方法都是对外可见的。
355381

356382
```javascript
357-
{
358-
let Foo = class {};
359-
class Bar extends Foo {
383+
class Widget {
384+
foo (baz) {
385+
bar.call(this, baz);
360386
}
387+
388+
// ...
389+
}
390+
391+
function bar(baz) {
392+
return this.snaf = baz;
361393
}
362394
```
363395

364-
上面的代码不会报错,因为`class`继承`Foo`的时候,`Foo`已经有定义了。但是,如果存在Class的提升,上面代码就会报错,因为`class`会被提升到代码头部,而`let`命令是不提升的,所以导致`class`继承`Foo`的时候,`Foo`还没有定义。
396+
上面代码中,`foo`是公有方法,内部调用了`bar.call(this, baz)`。这使得`bar`实际上成为了当前模块的私有方法。
397+
398+
还有一种方法是利用`Symbol`值的唯一性,将私有方法的名字命名为一个Symbol值。
399+
400+
```javascript
401+
const bar = Symbol('bar');
402+
const snaf = Symbol('snaf');
403+
404+
export default subclassFactory({
405+
406+
// 共有方法
407+
foo (baz) {
408+
this[bar](baz);
409+
}
410+
411+
// 私有方法
412+
[bar](baz) {
413+
return this[snaf] = baz;
414+
}
415+
416+
// ...
417+
});
418+
```
419+
420+
上面代码中,`bar``snaf`都是Symbol值,导致第三方无法获取到它们,因此达到了私有方法和私有属性的效果。
365421

366422
### 严格模式
367423

368424
类和模块的内部,默认就是严格模式,所以不需要使用`use strict`指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。
369425

370426
考虑到未来所有的代码,其实都是运行在模块之中,所以ES6实际上把整个语言升级到了严格模式。
371427

428+
### name属性
429+
430+
由于本质上,ES6的Class只是ES5的构造函数的一层包装,所以函数的许多特性都被Class继承,包括`name`属性。
431+
432+
```javascript
433+
class Point {}
434+
Point.name // "Point"
435+
```
436+
437+
`name`属性总是返回紧跟在`class`关键字后面的类名。
438+
372439
## Class的继承
373440

374441
### 基本用法

docs/module.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ $ compile-modules convert -o out.js file1.js
967967

968968
```html
969969
<script>
970-
System.import('./app');
970+
System.import('./app.js');
971971
</script>
972972
```
973973

0 commit comments

Comments
 (0)