首页 > 技术文章 > ES6——class类

shige720 2019-09-08 14:19 原文

  在其他的众多编程语言中(例如Python),都有class(类)这个概念,而JS在ES6规范中终于补上了

 

定义

  类是具有一些相同特征的对象,例如车都有颜色、轮子、座椅等元素,还有行驶时速,只不过不同的车,这些特征的是不一样的

  实际上class的本质,一方面是面向对象的思想,另一方面则是封装

 

声明

  声明class时,我们直接用class关键字+类名,在其中添加构造函数constructor来给后续实例化的对象添加属性/方法,这里的this就指向实例化被生成的对象

  这里的构造函数必须命名成constructor,用来接收实例化时传入的参数(也就是new 类名后的参数),但是具体如何处理还得看构造函数内部的书写

  类比于对象中的方法,也可以给类添加方法,例如图例中的speedUp,相比于constructor是独立存在的

  其实某种程度上说,class有点像工厂模式声明对象

  

 

方法

静态方法&静态属性

  静态方法/属性是在类里声明的,只属于类自己的,不可被类实例拥有,只是类自己拥有

  静态方法声明时用static关键字,写在类的内部,而静态属性则用类名.属性名=属性值的方法声明,可以写在类的内部/外部

  此外,类里的方法和静态方法如果同名不会引起冲突

  

静态属性的应用

获取类实例的数量

  可以用静态属性来检测这个类的实例的数量,原理就是每次创建一个新的类,都是在调用类里的constructor方法,里面的代码都会被执行

  这里由于Car.num这个属性是一个全局变量,因此不会被回收,但注意要在声明对象前挂上静态属性,否则无法修改静态属性

  

把和类相关的内容挂到静态属性上

  相比于直接在类上添加属性(动态,依靠外界传入),可以在类上绑定一个静态属性,这个属性的属性值可以通过访问类来找到

  好处在于:让属性和类关联,避免污染全局

  

静态方法的应用

提供一个公共的类相关的方法

  这里主要是提供一个类的方法,不用实例化生成对象就可直接调用的方法

  

 

类表达式

  可以模仿函数表达式,把一个类赋值给一个常量/变量(主要看声明)

  注意声明时,类名可以在类中访问,但不可在类外面访问(这一点也类似于函数的表达式声明)

  

  类表达式还可以自执行(类似于函数的特性),但实际开发中基本不用

  

 

getter/setter

  类似于在属性中提供一个钩子,可以在获取/设置属性值时候做一些额外的事情,这些事情在设置/访问之前执行

  实际上在ES5中,get/set方法就有了,可以添加在对象中,用get/set声明+属性名+(){}的方法声明(也可以理解成声明一个与属性名同名的函数),表示在访问/修改属性的时候会执行的操作

  注意set中必须传入一个参数,即为设置的属性值,否则报错

  如果执行的操作有和获取/修改属性相关的,则可能引发栈内存溢出

  

  也可以用Object的defineProperty方法来设置,直接在第三个参数里写上get和set的两个函数,相当于给对象添加两个方法

  不同于方法中的set,这里set函数中不一定要加形参

  

  需要注意以下问题:

  1.用defineProperty方法添加的属性不可用for-in语句遍历到的,需要给其添加enumerable属性(true),但是该属性一旦设置不可修改,否则报错

  (补充案例)

  2.如果一个属性有get和set方法,必须用defineProperty方法设置其为writable,否则属性是无法被修改的

  (案例)

  此外,访问/设置属性时,先调用get/set方法,再调用输出(console.log)等方法

  (补充个案例说明问题)

  (关于set和get实在是太多地方不理解……)

 

属性

name

  用来获取类的名称

  如果是类表达式声明,有类名称则返回类名称,否则返回赋值的变量名称

  

new.target

  返回的是new声明后的类/函数

  该属性不可直接调用,需要放在类/函数里

  

 

继承

  ES6的类也可以继承,其中被继承的类叫父类(基类),继承的类为子类

  类似于对象的继承,类的继承也可以让子类获取父类的方法和属性,从而实现子类属性/方法的添加

extends

  ES6的类中,可使用extends来继承父类的属性,并在constructor里给子类的属性赋值前,使用super方法来调用父类的构造函数,以实现继承

  

super

  上面的例子中可以看出,super可以在子类的构造函数中使用,以调用父类构造函数

  此外还可以作为对象的方式调用,但是在静态方法/非静态方法里使用时,访问到的分别是父类的原型/对象

  此外,在调用super时,父类的this始终是子类的this

  

推荐阅读