1. 理解
ES6引入Class的概念,以更接近传统语言的写法,作为对象的模板。
实际上,ES6的class
可以看作是一个语法糖,因为它的绝大部分功能,ES5都可以做到,新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
ES5:
function Point(x, y) { |
ES6:
class Point { |
注意:定义类的方法时,不需要加function
关键字,且两个方法间不需要逗号隔开
typeof Point; //"function"
Point === Point.prototype.constructor; //true
这证明类的数据类型本身就是函数,类本身就指向构造函数
构造函数的
prototype
属性继续存在,且类定义的函数都定义于prototype
上面类的新方法,可以直接添加在
prototype
上面
Object.assign(Point.prototype, { |
- 类中的所有方法都是不可枚举的(与ES5不同)
2. constructor方法
constructor
方法默认返回实例对象(this),可以指定返回另一个对象类必须用
new
调用,否则会报错,而构造方法不会
3. 类的实例
- 与ES5一样,实例的属性除非显示定义在其本身(即定义在
this
上),否则都是定义在原型上(即定义在class
上)
class Point { |
- 同ES5,所有实例共享一个原型对象
p1.__proto__ === p2.__proto__ //true
生产中,可以通过Object.getPrototypeOf
方法获取实例的原型,再为原型添加方法/属性(会应用于所有实例)
4. 注意点
- 类和模块内部,默认就是严格模式,不需要声明
- 不存在变量提升(hoist),类必须在声明之后才能调用(与继承有关)
- this的指向
类的方法内部如果含有this
,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错
class Logger { |
上面代码中,printName
方法中的this
,默认指向Logger
类的实例。但是,如果将这个方法提取出来单独使用,this
会指向该方法运行时所在的环境(由于 class 内部是严格模式,所以 this 实际指向的是undefined
),从而导致找不到print
方法而报错。
解决方法
class Logger { constructor() { this.printName = this.printName.bind(this); } // ... } <!--code6-->
使用
proxy
//TODO
5. 静态方法
在方法前,加上static
关键字,就表示该方法不会被实例继承,而是直接通过类来调用
class Foo { |
注意,如果静态方法包含this
关键字,这个this
指的是类,不是实例。
Todo…