Skip to content

ES6的Class

1、面向过程与面向对象

面向过程:面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。 面向对象:面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作

面向过程面向对象
优点性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机就采用的面向过程编程。易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护
缺点不易维护、不易复用、不易扩展性能比面向过程低

2、对象与类

  • 对象 对象是由属性和方法组成的:是一个无序键值对的集合,指的是一个具体的事物

属性:/(常用名词) 方法:事物的行为,在对象中用方法来表示(常用动词)

  • 类 在 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。类抽象了对象的公共部分,它泛指某一大类(class)对象特指某一个,通过类实例化一个具体的对象

2.1 创建类

关键字class 语法:class 类名 { } 例如:class Star

2.2 创建的类添加属性和方法

2.2.1 类的实例添加属性的方法

通常通过在构造函数当中,通过this进行变量赋值,而this指向实例本身 关键词

js
语法:constructor(构造函数形参 ){ this. 属性1=行参;...  }

constructor它是一个构造函数 (构造函数,用来初始化属性数据:) 类的共有属性放到 constructor 里面,constructor是 构造器或者构造函数

2.2.2 类添加方法

通过 方法(形参){ 方法体 } 来定义,注意方法与方法之间不需要添加逗号 例如:sing(song){ 执行代码 }

2.3 利用类创建对象

关键字new 类生成实例,是通过 new 类名(构造函数实参) 的方式来创建 例如:var ldh = new Star(' 刘德华')

注意

  1. 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
  2. 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
  3. constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
  4. 多个函数方法之间不需要添加逗号分隔,否则会报错
  5. 生成实例 new 不能省略
  6. 语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function

2.4 class类继承

Class 可以通过extends关键字实现继承,让子类继承父类的属性和方法。extends 的写法比 ES5 的原型链继承,要清晰和方便很多。

js
class Point {
}

class ColorPoint extends Point {
}

2.4.1 类继承注意

  • 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
  • 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
  • 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用父类的构造函数,super 必须在子类this之前调用
  • 子类继承父类里面的属性和方法,子类里面可以不用有consturctor函数,但是如果有这个函数,里面必须要有super,否组会报错
  • 子类构造函数中定义的变量,父类的方法中是可以通过this来访问到的,父类中的this指向子类的实例

2.4.2 为什么子类的构造函数,一定要调用super()

ES6 规定,若子类有constructor构造函数,子类必须在constructor()方法中调用super(),且super()必须定义在最前面,否则就会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。只有super()方法才能让子类实例继承父类。

为什么子类的构造函数,一定要调用super()?原因就在于 ES6 的继承机制,与 ES5 完全不同。ES5 的继承机制,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上面,即“实例在前,继承在后”。ES6 的继承机制,则是先将父类的属性和方法,加到一个空的对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”。这就是为什么 ES6 的继承必须先调用super()方法,因为这一步会生成一个继承父类的this对象,没有这一步就无法继承父类。

注意,这意味着新建子类实例时,父类的构造函数必定会先运行一次。

js
class Foo {
  constructor() {
    console.log(1);
  }
}

class Bar extends Foo {
  constructor() {
    super();
    console.log(2);
  }
}

const bar = new Bar();
// 1
// 2

2.5 super

既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。

super( ) 作为函数调用时:

  • 代表父类的构造函数。,
  • super()只能用在子类的构造函数之中,用在其他地方就会报错
  • ES6 要求,子类的构造函数必须执行一次super函数
  • super()虽然代表了父类的构造函数,但是返回的是子类的实例,即super()内部的this指的是B的实例

super.方法名( ) super作为对象时:

  • 若super在普通方法中,指向父类的原型对象(相当于Father.prototype),此时 ''定义在父类实例上的方法或属性,是无法通过super调用的''
  • 在静态方法中,指向父类。
  • 子类的super.只能访问父类的方法,不能访问父类的属性
  • 在子类constructor中通过super调用父类的方法时,若无此方法,则为undefined,有则为此方法,方法内部的this指向当前的子类实例 Image_20220525154415.png