简介
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。
| 1 | function Point(x, y) { | 
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
| 1 | //定义类 | 
- constructor: 构造方法,类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。- 一个类必须有 constructor 方法,如果没有显式定义,一个空的 constructor 方法会被默认添加。
 
- this: 关键对象
定义“类”的方法的时候,前面不需要加上 function 这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。
ES6 的类,完全可以看作构造函数的另一种写法。
| 1 | class Point { | 
构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。
| 1 | class Point { | 
在类的实例上面调用方法,其实就是调用原型上的方法。
| 1 | class B {} | 
由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign 方法可以很方便地一次向类添加多个方法。
| 1 | class Point { | 
类的属性名,可以采用表达式。
| 1 | let methodName = 'getArea' | 
类的实例对象
与 ES5 一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。
| 1 | //定义类 | 
hasOwnProperty: 查找对象原型上是否有某属性 (上面代码表示 toString 保存在Point类中,point 是通过原型链获得 toString 方法)
Class 表达式
与函数一样,类也可以使用表达式的形式定义。
| 1 | const MyClass = class Me { | 
如果类的内部没用到的话,可以省略Me,也就是可以写成下面的形式。
| 1 | const MyClass = class { | 
采用 Class 表达式,可以写出立即执行的 Class。
| 1 | let person = new class { | 
私有方法和私有属性
私有方法是常见需求,但 ES6 不提供,只能通过变通方法模拟实现。
在命名上加以区别:
| 1 | lass Widget { | 
将私有方法移出模块,因为模块内部的所有方法都是对外可见的:
| 1 | class Widget { | 
上面代码中,foo 是公有方法,内部调用了 bar.call(this, baz)。这使得 bar 实际上成为了当前模块的私有方法。
利用Symbol值的唯一性,将私有方法的名字命名为一个Symbol值:
| 1 | onst bar = Symbol('bar'); | 
上面代码中,bar 和 snaf 都是 Symbol 值,导致第三方无法获取到它们,因此达到了私有方法和私有属性的效果。
this 的指向
类的方法内部如果含有this,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错。
| 1 | class Logger { | 
解决办法
- 在构造方法中绑定this
| 1 | class Logger { | 
- 箭头函数
| 1 | class Logger { | 
- 使用Proxy,获取方法的时候,自动绑定this
| 1 | unction selfish (target) { | 
getter setter
与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
| 1 | class MyClass { | 
存值函数和取值函数是设置在属性的 Descriptor 对象上的
Class 的 Generator 方法
todo // 对 Generator 不熟悉,待下次理解了在写
Class 的静态方法
静态方法:不会被实例继承,而是直接通过类来调用。
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用
| 1 | class Foo { | 
注意,如果静态方法包含
this关键字,这个this指的是类,而不是实例。
| 1 | class Foo { | 
父类的静态方法,可以被子类继承。
| 1 | class Foo { | 
静态方法也是可以从super对象上调用的
| 1 | class Foo { | 
Class 的静态属性和实例属性
静态属性:Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
| 1 | class Foo {} | 
ES6 明确规定,Class 内部只有静态方法,没有静态属性
写法无效如下:
| 1 | // 以下两种写法都无效 | 
类的实例属性
类的实例属性可以用等式,写入类的定义之中
| 1 | class MyClass { | 
类的静态属性
类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了。
| 1 | class MyClass { |