类是什么?原型如何实现继承?Class 如何实现继承?Class 本质是什么?
类是什么?
类(class)这个概念来源于OOP(Object Oriented Programming),也就是面向对象编程,OOP是一种计算机编程架构,其有着封装,继承,多态三种特性。而类在OOP中是实现信息封装的基础。
类是一种用户定义类型,也称类类型。
每个类包含数据说明和一组操作数据或传递消息的函数。
类的实例称为对象。
抽取(抽象)对象的公用的属性和行为组织(封装)成一个类(模板)
例如把手机的所有功能抽取出来,成为一个模板,如果想生产手机,对类进行实例化,获取类的对象
①创建类
//创建类
class Star { //通过class关键字创建类,类名大写
constructor(uname,age){ //类里面有个constructor函数,可以接受传递过来的参数,返回实例对象
this.uname = uname; //new的使用自动调用constructor,没有写也会自动生成
this.age=age
}
}
//利用类创建对象 new //new不能省略
var ldh = new Star('刘德华',18)
console.log(ldh.uname)//-> 刘德华
②类添加方法
//创建类
class Star {
constructor(uname,age){
this.uname = uname;
this.age=age
}
sing(song){ //类里面的所有函数不需要写function
console.log(this.uname + song) //多个函数之间不需要添加逗号分隔
}
}
//利用类创建对象 new
var ldh = new Star('刘德华',18)
console.log(ldh.uname)//-> 刘德华
ldh.sing('冰雨')//->刘德华冰雨
③类的继承
class Father{
constructor(){}
money(){
console.log(100)
}
}
class Son extends Father{}
var son = new Son();
son.money(); //-> 100
//------------------------------------
class Father{
constructor(){
this.x = x;
this.y = y;
}
sum(){
console.log(this.x+this.y)
}
}
class Son extends Father{
constructor(x,y){
this.x = x;
this.y = y;
}
}
var son = new Son(1,2);
son.sum(); //->会报错:原因,父类里面的sum的this指向的是父类里面的this
//这样传递,父类里面的x和y是没有值的
④super关键字
//super调用父类的构造函数
class Father{
constructor(){
this.x = x;
this.y = y;
}
sum(){
console.log(this.x+this.y)
}
}
class Son extends Father{
constructor(x,y){
super(x,y) //调用了父类中的构造函数
}
}
var son = new Son(1,2);
var son2 = new Som(11,22)
son.sum(); //->3
son2.sum(); //->33
//super调用父类普通函数
class Father{
say(){
return '我是爸爸'
}
}
class Son extends Father{
say(){
console.log('我是儿子')
}
}
var son = new Son();
son.say();//我是儿子 //就近原则,子类里面有就去子类里面拿,然后再找父类
class Son2 extends Father{
sqy(){
console.log(super.say()+'的儿子')
}
}
var son2 = new Son2();
son2.say()//-> 我是爸爸的儿子
⑤子类继承父类方法同时扩展自己方法
class Father{
constructor(x,y){
this.x = x;
this.y = y;
}
sum(){
console.log(this.x + this.y)
}
}
//子类
class son extends Father{
constructor(x,y){
super(x,y) //调用父类的constructor
this.x = x; //子类在构造函数中使用super,必须放在this前面
this.y = y;
}
subtract(){
console.log(this.x - this.y)
}
}
注意:类必须先写在实例前面才可以,类里面的共有属性和方法一定要加this
Class的本质是什么?
首先先来讲下 class
,其实在 JS 中并不存在类,class
只是语法糖,本质还是函数。
class Person {}
Person instanceof Function // true
ES5之前的类是什么?
function 士兵(id,hp){
this.id = id
this.hp = hp
}
士兵.prototype = {
constructor:士兵()
walk:function(){ } ,
Shooting:function(){ } ,
}
ES6中引入class关键字
class 士兵{
constructor(id,hp) {
this.id = id;
this.hp = hp;
}
walk() {},
Shooting(){}
}
通过原型实现类的继承
组合继承
组合继承是最常用的继承方式,
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function() {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = new Parent()
const child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
以上继承的方式核心是在子类的构造函数中通过 Parent.call(this)
继承父类的属性,然后改变子类的原型为 new Parent()
来继承父类的函数。
这种继承方式优点在于构造函数可以传参,不会与父类引用属性共享,可以复用父类的函数,但是也存在一个缺点就是在继承父类函数的时候调用了父类构造函数,导致子类的原型上多了不需要的父类属性,存在内存上的浪费。
可以使用寄生方法来继承避免内存上的浪费,在本文中就不过多赘述,感兴趣的小伙伴可以查找一下。