前言
Class为es6之后推荐的为了更加体现面向对象思想的一种方式,但从本质上来说它还是原型链的关系,也就是语法糖。而function构造函数的方法则是es6之前常规的面向对象思想体现的一种方式。
本篇文章涉及的原理较多,可以结合下列文章:
面向对象思想、构造函数和原型及两者作用、原型链以及方法执行顺序
class本质
在理解class本质之前,我们先根据构造函数的特性:
- 构造函数具有原型对象prototype
- 构造函数中的原型对象prototype里有constructor指向构造函数本身
- 构造函数可以通过原型对象添加方法
- 构造函数创建的实例对象有__ proto __原型指向构造函数的原型对象
那么,我们利用class Person{}
创建出来的类,是否存在这些特征?
由下图可知,类同样有原型对象prototype且prototype中的constructor同样指向Person类,即证明了1和2两个论点
同样的我们继续论证,添加方法
Person.prototype.sing=function(){
console.log("唱歌");
}
let person=new Person("cc",20);
由下图,实例对象中存在__ proto __属性指向构造函数的原型对象且添加了sing方法因此class类与构造函数之间原理是相同的,class是为了更直观体现出面向对象。
对象设计
class
class Person {
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
sing(){
console.log("唱歌");
}
}
let person=new Person("ck",20);
function
function Person(uname, age){
this.uname = uname;
this.age = age;
}
Person.prototype.sing= function(){
console.log("唱歌");
}
let person=new Person("ck",20);
静态方法
PS:Class 内部只有静态方法,没有静态属性。如果必须定义则类似于函数定义静态成员变量的方式:
Person.sex="男"
之后通过调用静态成员的方式调用即可。
类的静态方法:在类中添加static
,例如:
static dance(){
console.log("跳舞");
}
重点:
- 如果静态方法包含this关键字,这个this指的是类,而不是实例。
- 父类的静态方法,可以被子类继承或子类中用
super
调用。
继承
类的继承实现有extends
关键字
class Son extends Person{
constructor(uname, age) {
super(uname,age)
}
}
此时的super
方法必须在constructor内部的第一行,即子类的constructor方法没有调用super
之前,就使用this
关键字,结果报错,而放在super
方法之后就是正确的。
构造函数的实现继承
function Son(uname,age){
Person.call(this,uname,age)
}
Son.prototype=new Person();
let son=new Son("ck",20)
注意构造函数的继承方法则是利用call
、apply
改变指针,同时子对象Son
的原型对象prototype
指向Person
的实例对象,于是便与Person
的原型链连接起来但却独立拥有自己的属性和方法。