前言
总所周知,咱们传统的生成实例对象的方法是通过构造函数:
1 | function Point(x, y) { |
现在 ES6 提供Class(类)的概念,一个语法糖,作为对象的模板。自从有了Class,咱们生成实例对象的写法就更加清晰,更像面对对象的语法。
1 | class Point { |
解析:类里面有个constructor方法——构造方法,this指向实例对象;咱们ES5的构造函数Point就相当于ES6的Point类的constructor方法
定义方法,也只需要直接写在类里面就好了。构造函数的prototype属性,在类上依然存在。(类上的所有方法都定义在类的prototype属性上)
严格模式(注意)
ES6里面默认是严格模式,只要代码写在类或模块里面,就只有严格模式可用哦。
深入Class的老窝
constructor方法
类的默认方法,new生成实例对象时,自动调用。如果没有自定义,会默认加上空的constructor(所以是类里必须的方法)
默认返回实例对象(this),也可以指定返回另一个对象
1 | class Person { |
实例对象
生成的方式仍然是new命令。注意:实例的属性除非是定义在this对象(显示定义在本身,constructor方法),否则都是定义在原型(类)上
1 | class Point { |
表达式
类可以用表达式的形式定义
1 | const MyClass = class Me { |
注意:这个类的名字叫MyClass而不是Me,Me只有在Class内部有定义
1 | let inst = new MyClass(); |
如果类的内部没有用到,可以省略Me
1 | const MyClass = class { |
也可以写出立即执行Class
1 | let person = new class { |
不存在变量提升
即类使用在前,定义在后会报错的。原因和继承相关,必须保证子类在父类之后定义。
this的指向
如果类里面的某个方法有this,默认指向类的实例,但是如果把这个方法单独使用,会指向该方法运行时的环境,一般会指到window
1 | class Test { |
getter和setter
可以在类内部使用get和set,对某个属性设置存值函数和取值函数,拦截该属性的存取行为
1 | class MyClass { |
静态方法、静态属性、实例属性(重中之重)
类相当于实例的原型,所有类有的东西,都会被实例继承
1、静态方法
- 类自己的方法,不会被实例继承
使用方法:方法前面加 static关键字(此方法可以被类调用)
1 | class Foo { |
注意1:静态方法的this指向类,而不是实例
1 | class Foo { |
注意2:父类的静态方法可以被子类继承;也可以从super对象上调用
2、静态属性和实例属性
静态属性: 类自己的属性,不会被实例继承
因为ES6明确规定,class内没有静态属性,所以只有下面形式可行
1 | class Foo {} |
但是ES7有一个提案:对静态属性和实例属性规定了新的写法。目前Babel转码器支持。
静态属性
在属性前面加static关键字
1 | class Foo { |
实例属性
之前的实例属性只能写在类的construtor方法里
1 | class ReactCounter extends React.Component { |
现在写法更清晰
1 | class ReactCounter extends React.Component { |
并且在constructor里面定义的实例属性,还可以直接列出
1 | class ReactCounter extends React.Component { |
总结
- 类声明不可以提升
- 类声明不允许再次声明已经存在的类,否则将会抛出一个类型错误
- class 内部是严格模式,构造函数是可选的;如果没有自定义,会默认加上空的constructor
- class 的静态方法或者原型方法都不可枚举,且这些方法都没有原型,不可被 new
- class 必须使用 new 来调用
- class 内部无法重写类名
- class 静态方法与静态属性
- 静态方法前加 static 关键字
- 只能通过类名调用
- 不能通过实例调用
- 可与实例方法重名
- 静态方法中的 this 指向类而非实例
- 静态方法可被继承
- 子类中可通过 super 方法调用父类的静态方法
- Class 内部没有静态属性,只能在外面通过类名定义