1.简介:ES6 Class(类)是 ES5构造函数的语法糖
// ES5
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function() {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
// ES6
class Point {
constructor(x, y) {
// constructor()方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
// x和y都是实例对象point自身的属性(因为定义在this对象上),
this.x = x;
this.y = y;
// return Object.create(null);
}
// toString()是原型对象的属性(因为定义在Point类上)
toString() {
return `(${this.x},${this.y})`
}
}
const point = new Point(1, 2)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
2静态方法(只能构造函数本身调用,实例无法调用)
class Foo {
static bar() {
// 2.1 如果静态方法包含this关键字,这个this指的是类,而不是实例。
this.baz();
}
static baz() {
console.log('hello');
}
baz() {
console.log('world');
}
}
Foo.bar() // hello()
var foo = new Foo();
// foo.bar() //// TypeError: foo.bar is not a function
// 2.2 父类的静态方法,可以被子类继承。
class Bar extends Foo {
static bar() {
//2.3 静态方法也是可以从super对象上调用的。
return super.bar() + ', too';
}
}
Bar.bar() //fix 没有打印too
3实例属性的新写法
实例属性除了定义在constructor()方法里面的this上面,也可以定义在类的最顶层。
class IncreasingCounter {
constructor() {
this._count = 0;
}
get value() {
console.log('Getting the current value!');
return this._count;
}
increment() {
this._count++;
}
}
class IncreasingCounter {
// 这时,不需要在实例属性前面加上this。
_count = 0;
get value() {
console.log('Getting the current value!');
return this._count;
}
increment() {
this._count++;
}
}
4 静态属性
静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
// 老写法
class Foo {
// ...
}
Foo.prop = 1;
// 新写法
class Foo {
static prop = 1;
}
5 私有方法和私有属性
私有方法和私有属性,是只能在类的内部访问的方法和属性,外部不能访问。这是常见需求,有利于代码的封装,但 ES6 不提供,只能通过变通方法模拟实现。
私有属性的提案 : 目前,有一个提案,为class加了私有属性。方法是在属性名之前,使用#表示。
注意点: (1)严格模式:类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式 (2)不存在提升 (3)name 属性 (4)Generator 方法 (5)this 的指向
类的方法内部如果含有this,它默认指向类的实例.但是,必须非常小心,一旦单独使用该方法,很可能报错。
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
const {
printName
} = logger;
printName(); // TypeError: Cannot read property 'print' of undefined
一个比较简单的解决方法是,在构造方法中绑定this,这样就不会找不到print方法了。
class Logger {
constructor() {
this.printName = this.printName.bind(this);
}
// ...
}
另一种解决方法是使用箭头函数。
class Obj {
constructor() {
this.getThis = () => this;
}
}
const myObj = new Obj();
myObj.getThis() === myObj // true
还有一种解决方法是使用Proxy,获取方法的时候,自动绑定this。