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

docs(class): edit class

This commit is contained in:
ruanyf 2017-08-17 20:10:28 +08:00
parent 65d6aff64c
commit 2eb11d7026
4 changed files with 30 additions and 20 deletions

View File

@ -668,6 +668,26 @@ foo.classMethod()
上面代码中,`Foo`类的`classMethod`方法前有`static`关键字,表明该方法是一个静态方法,可以直接在`Foo`类上调用(`Foo.classMethod()`),而不是在`Foo`类的实例上调用。如果在实例上调用静态方法,会抛出一个错误,表示不存在该方法。
注意,如果静态方法包含`this`关键字,这个`this`指的是类,而不是实例。
```javascript
class Foo {
static bar () {
this.baz();
}
static baz () {
console.log('hello');
}
baz () {
console.log('world');
}
}
Foo.bar() // hello
```
上面代码中,静态方法`bar`调用了`this.baz`,这里的`this`指的是`Foo`类,而不是`Foo`的实例,等同于调用`Foo.baz`。另外,从这个例子还可以看出,静态方法可以与非静态方法重名。
父类的静态方法,可以被子类继承。
```javascript

View File

@ -2,7 +2,7 @@
## 类的修饰
修饰器Decorator是一个函数用来修改类的行为。ES2017 引入了这项功能,目前 Babel 转码器已经支持
许多面向对象的语言都有修饰器Decorator函数用来修改类的行为。目前有一个[提案](https://github.com/tc39/proposal-decorators)将这项功能,引入了 ECMAScript
```javascript
@testable

View File

@ -1085,20 +1085,6 @@ myElement.addEventListener('click', function() {
上面代码中,`myElement`是一个 DOM 节点,每当发生`click`事件,就更新一下状态。我们将这个状态作为键值放在 WeakMap 里,对应的键名就是`myElement`。一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。
进一步说,注册监听事件的`listener`对象,就很合适用 WeakMap 实现。
```javascript
const listener = new WeakMap();
listener.set(element1, handler1);
listener.set(element2, handler2);
element1.addEventListener('click', listener.get(element1), false);
element2.addEventListener('click', listener.get(element2), false);
```
上面代码中,监听函数放在 WeakMap 里面。一旦 DOM 对象消失,跟它绑定的监听函数也会自动消失。
WeakMap 的另一个用处是部署私有属性。
```javascript

View File

@ -499,7 +499,7 @@ class Even {
### Symbol.isConcatSpreadable
对象的`Symbol.isConcatSpreadable`属性等于一个布尔值,表示该对象使`Array.prototype.concat()`时,是否可以展开。
对象的`Symbol.isConcatSpreadable`属性等于一个布尔值,表示该对象用`Array.prototype.concat()`时,是否可以展开。
```javascript
let arr1 = ['c', 'd'];
@ -511,9 +511,9 @@ arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
```
上面代码说明,数组的默认行为是可以展开`Symbol.isConcatSpreadable`属性等于`true``undefined`,都有这个效果。
上面代码说明,数组的默认行为是可以展开`Symbol.isConcatSpreadable`默认等于`undefined`。该属性等于`true`时,也有展开的效果。
类似数组的对象也可以展开,但它的`Symbol.isConcatSpreadable`属性默认为`false`,必须手动打开。
类似数组的对象正好相反,默认不展开。它的`Symbol.isConcatSpreadable`属性设为`true`,才可以展开。
```javascript
let obj = {length: 2, 0: 'c', 1: 'd'};
@ -523,7 +523,7 @@ obj[Symbol.isConcatSpreadable] = true;
['a', 'b'].concat(obj, 'e') // ['a', 'b', 'c', 'd', 'e']
```
对于一个类来说,`Symbol.isConcatSpreadable`属性必须写成实例的属性
`Symbol.isConcatSpreadable`属性也可以定义在类里面
```javascript
class A1 extends Array {
@ -535,7 +535,9 @@ class A1 extends Array {
class A2 extends Array {
constructor(args) {
super(args);
this[Symbol.isConcatSpreadable] = false;
}
get [Symbol.isConcatSpreadable] () {
return false;
}
}
let a1 = new A1();
@ -550,6 +552,8 @@ a2[1] = 6;
上面代码中,类`A1`是可展开的,类`A2`是不可展开的,所以使用`concat`时有不一样的结果。
注意,`Symbol.isConcatSpreadable`的位置差异,`A1`是定义在实例上,`A2`是定义在类本身,效果相同。
### Symbol.species
对象的`Symbol.species`属性,指向当前对象的构造函数。创造实例时,默认会调用这个方法,即使用这个属性返回的函数当作构造函数,来创造新的实例对象。