Ld8gX4mUp-A.jpg

起步

新增的类,其实就是ES5中的普通的function, 是基于原型函数的继承
那么在ES6前,我们的类是怎么实现的,可以从以下入口进入学习

入口:构造函数学习

基本使用

类怎么写

  1. class Star {}

怎么定义类属性=>name即为这个属性的key

  1. class Father {
  2. // 用于定于该类的属性-key,如果不写,在实例化的时候也会隐式生成一个
  3. constructor(x, y) {
  4. this.x = x
  5. this.y = y
  6. }
  7. }

怎么加这个类的方法

  1. class Father{
  2. // 用于定于该类的属性-key,如果不写,在实例化的时候也会隐式生成一个
  3. constructor(x, y) {
  4. this.x = x
  5. this.y = y
  6. }
  7. //定义在类上的方法
  8. sum () {
  9. console.log(this.x + this.y)
  10. }
  11. }

怎么使用这个类

使用类,就需要实例化这个类,让它表示具体的某个对象,比如:

  1. class Father{
  2. // 用于定于该类的属性-key,如果不写,在实例化的时候也会隐式生成一个
  3. constructor(x, y) {
  4. this.x = x
  5. this.y = y
  6. }
  7. //定义在类上的方法
  8. sum () {
  9. console.log(this.x + this.y)
  10. }
  11. }
  12. var son = new Father(1,2)
  13. son.sum()
  14. //输出3

son实例化了这个father类,也能使用这个类的方法,在实例化后,默认已经执行了constructor中的函数,调用sum方法后,可以直接相加得到3

怎么理解继承

继承表面意思很好理解,就是子继承了父的所有属性和方法,用最简单的代码来表达这个概念就是

extends

extends就是继承,看到extends就是用了继承

  1. class Father{
  2. constructor() {
  3. }
  4. //定义在类上的方法
  5. money () {
  6. console.log('我有100元')
  7. }
  8. }
  9. class Son extends Father {
  10. }

继承后有什么用,怎么体现继承成功了

  1. class Father{
  2. constructor() {
  3. }
  4. //定义在类上的方法
  5. money () {
  6. console.log('我有100元')
  7. }
  8. }
  9. class Son extends Father {
  10. }
  11. var test = new Son()
  12. test.money()
  13. // 输出'我有100元'

直接实例化son这个类,它就拥有son继承的那个类的所有属性和方法,就像是money()这个方法,money()是在Father这个类中定义的

就近原则

  1. class Father{
  2. //定义在类上的方法
  3. money () {
  4. console.log('我有100元')
  5. }
  6. }
  7. class Son extends Father {
  8. money() {
  9. console.log('我有200元')
  10. }
  11. }
  12. var test = new Son()
  13. test.money()

super在类里面怎么用

继续我们上面的函数,我们继承了一个简单的方法,接下来写个计算函数

  1. class Father{
  2. constructor(x,y) {
  3. this.x = x
  4. this.y = y
  5. }
  6. //定义在类上的方法
  7. money () {
  8. console.log('我有100元')
  9. }
  10. sum () {
  11. console.log(this.x + this.y)
  12. }
  13. }
  14. class Son extends Father {
  15. //这里注意了就算是继承了父类的方法,如果有需要依赖的属性,
  16. //要是要在子类里重新定义的
  17. constructor(x,y) {
  18. this.x = x
  19. this.y = y
  20. }
  21. }
  22. var test = new Son(1, 2)
  23. test.sum()

现在貌似没什么问题,理想输出应该是3
我们执行以下
image.png
可以看到this那里出现了问题,哦,其实这个问题很好理解
sum是父类中的方法,依赖的this.x和this.y是父类的,
Son类中的this.x和this.y这里是子类的即为Son的,我们想用父类的方法,就需要改变子类的指针this,让this指向父类

指针不能直接继承是要处理的

修改下函数

  1. class Father{
  2. constructor(x,y) { // 构造函数
  3. this.x = x
  4. this.y = y
  5. }
  6. //定义在类上的方法
  7. money () {
  8. console.log('我有100元')
  9. }
  10. sum () {
  11. console.log(this.x + this.y)
  12. }
  13. }
  14. class Son extends Father {
  15. constructor(x,y) {
  16. super(x,y) //调用了父类的构造函数
  17. }
  18. }
  19. var test = new Son(1, 2)
  20. test.sum()
  21. //输出3

其实在类中super可以调用父类的构造函数也可以调用普通函数

  1. class Father{
  2. constructor(x,y) { // 构造函数
  3. this.x = x
  4. this.y = y
  5. }
  6. //定义在类上的方法
  7. money () {
  8. return '我有100元'
  9. }
  10. sum () {
  11. console.log(this.x + this.y)
  12. }
  13. }
  14. class Son extends Father {
  15. constructor(x,y) {
  16. super(x,y) //调用了父类的构造函数
  17. }
  18. money() {
  19. console.log(super.money() + ',加上我之前存的,我有500元')
  20. }
  21. }
  22. var test = new Son(1, 2)
  23. test.money()

我们可以看到运行结果,是不是不难理解

image.png

在继承的情况下,我子类新增的独有方法和父类的方法依赖用一个数据源,this怎么去处理,会不会冲突

  1. class Father{
  2. constructor(x,y) { // 构造函数
  3. this.x = x
  4. this.y = y
  5. }
  6. //定义在类上的方法
  7. money () {
  8. return '我有100元'
  9. }
  10. sum () {
  11. console.log(this.x + this.y)
  12. }
  13. }
  14. class Son extends Father {
  15. constructor(x,y) {
  16. //特别注意super必须要在子类this之前调用
  17. super(x,y) //调用了父类的构造函数 --为了使用sum
  18. this.x = x //同时,x,y也指向自己,可以只用自己的独有方法
  19. this.y = y
  20. }
  21. subtract() {
  22. console.log(this.x - this.y)
  23. }
  24. money() {
  25. console.log(super.money() + ',加上我之前存的,我有500元')
  26. }
  27. }
  28. var test = new Son(1, 2)
  29. test.subtract()

我们看下结果
image.png
OK,我们达到了目的!ES6中的类的使用你Get了吗?

特点回顾

  • 在ES6中的类没有变量提升,所以必须先定义类,才能实例化对象
  • 类里面共有的属性和方法如果要用,一定要加this才能长成调用

  • 当你使用class的时候,它会默认调用constructor这个函数,来接收一些参数,并构造出一个新的实例对象(this)并将它返回。

  • 如果你的class没有定义constructor,也会隐式生成一个constructor方法

  • constructorvar一个变量,它只存在于constructor这个构造函数中

  • constructor中使用this定义的属性和方法会被定义到实例上,也就是它指向的是实例化对象
  • class中使用=来定义一个属性和方法,效果与第二点相同,会被定义到实例上
  • class中直接定义一个方法,会被添加到原型对象prototype
  • class中使用了static修饰符定义的属性和方法被认为是静态的,被添加到类本身,不会添加到实例上