ES6随笔

参考资料:阮一峰 ES6 标准入门教程第三版

本文用于记录我觉得 ES6 中重要的原理和使用技巧

class 的继承

Class 可以通过 extends 关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

1
2
3
4
5
6
7
8
9
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
toString() {
return this.color + " " + super.toString(); // 调用父类的toString()
}
}

子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是因为子类自己的 this 对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用 super 方法,子类就得不到 this 对象。

ES5 的继承,实质是先创造子类的实例对象 this,然后再将父类的方法添加到 this 上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到 this 上面(所以必须先调用 super 方法),然后再用子类的构造函数修改 this。


20220502 更新

构造函数的 prototype 属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的 prototype 属性上面。 –阮一峰《ES6》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};

当我想打印输出看一下console.log(Point.prototype)的时候输出却是{},感到很奇怪,明明方法是定义在prototype属性上的,为什么输出确实空的呢?

查了一下发现:

这是因为 console.log()使用了 util.inspect(),它使用了 Object。对象上的keys(),它只返回可枚举的属性。并且 Object.prototype 包含非可枚举属性,这就是它返回空节点的原因。

因为那些方法都默认是不可枚举的,所以当我们想定义一个可枚举的属性时可以使用Object.defineProperty()

1
2
3
4
5
6
7
8
Object.defineProperty(Point.prototype, "hh", {
value: function () {
console.log(3);
},
// 可枚举
enumerable: true,
});
console.log(Point.prototype);

这下打印出了{ hh: [Function: value] }



ES6随笔
https://zouhualu.github.io/20220114/ES6随笔/
作者
花鹿
发布于
2022年1月14日
许可协议