本文是记录ES6文档的Class章节的读书笔记,建议先阅读文档
Points
- Es6的class可以看做只是一个语法糖
- 通过Object.assign方法可以一次向类添加多个方法
- 与ES5的行为不同的是,Class内部所有定义的方法都是不可枚举的
- 类的属性名,可以采用表达式
- 一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加
- constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
- S5的行为一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)
- 与ES5的行为一样,类的所有实例共享一个原型对象
- 与ES5行为完全不同的是,Class不存在变量提升(hoist)
- 与函数一样,类也可以使用表达式的形式定义,可以写出立即执行的Class
- ES6不提供私有方法,只能通过变通方法模拟实现
- Class中this的指向
- ES5继承机制 VS ES6继承机制
- 类的prototype属性和__proto__属性
- 子类的Super使用,必须显式指定是作为函数、还是作为对象使用,否则会报错
- Class的取值函数(getter)和存值函数(setter)
- Class的Generator方法
- Class的静态方法
- Class的静态属性和实例属性
- Mixin模式的实现
Es6的class可以看做只是一个语法糖
//传统方法是通过构造函数,定义并生成新对象
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var p = new Point(1, 2);
通过Object.assign方法可以一次向类添加多个方法
由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法。
class Point {
constructor(){
// ...
}
}
Object.assign(Point.prototype, {
toString(){},
toValue(){}
});
与ES5的行为不同的是,Class内部所有定义的方法都是不可枚举的
//ES5
var Point = function (x, y) {
// ...
};
Point.prototype.toString = function() {
// ...
};
Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]
//ES6
class Point {
constructor(x, y) {
// ...
}
toString() {
// ...
}
}
Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]
类的属性名,可以采用表达式
let methodName = "getArea";
class Square{
constructor(length) {
// ...
}
[methodName]() {
// ...
}
}
constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象
class Foo {
constructor() {
return Object.create(null);
}
}
new Foo() instanceof Foo
// false
S5的行为一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
上面代码中,x和y都是实例对象point自身的属性(因为定义在this变量上),所以hasOwnProperty方法返回true,而toString是原型对象的属性(因为定义在Point类上),所以hasOwnProperty方法返回false。这些都与ES5的行为保持一致。
与ES5的行为一样,类的所有实例共享一个原型对象
var p1 = new Point(2,3);
var p2 = new Point(3,2);
p1.__proto__ === p2.__proto__
//true
上面代码中,p1和p2都是Point的实例,它们的原型都是Point.prototype,所以__proto__属性是相等的。