当前位置:   article > 正文

JS中Class类的继承_js class继承

js class继承

Class继承

    Class 可以通过 extends 关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多

class Animate {
	constructor() {
    	// 默认返回实例对象 this
    }
}
class Dog extends Animate {
	constructor() {
		super()
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

    子类必须在 constructor 方法中调用super方法,否则新建实例时会报错,子类就得不到 this 对象。这是因为子类自己的 this 对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工。如果不调用 super 方法,子类就得不到this对象。
    ES5 的继承,实质是先创造子类的实例对象 this,然后再将父类的方法添加到 this 上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到 this上面(所以必须先调用super方法),然后再用子类的构造函数修改 this。

1. this 关键字的使用

    在子类的构造函数中,只有调用 super 之后,才可以使用 this 关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有 super 方法才能调用父类实例。

class Animate {
	constructor(x, y) {
    	// 默认返回实例对象 this
    }
}
class Dog extends Animate {
	constructor(x, y, z) {
		this.z = z    //  ReferenceError
		super(x, y)   //  this 只能在super() 方法调用之后再使用
		this.z = z 
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2. 父类的静态方法会被子类继承

    通过子类的类名去调用继承的父类静态方法

class Animate {
	constructor() {
	    // 默认返回实例对象 this
	}
	static show() {
	    console.log('我是show方法')
	}
}

class Dog extends Animate {
	constructor() {
		super()
	}
}
var dog = new Dog()
Dog.show()     //  我是show方法
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3. 子类中重写父类的方法
    如果在子类中也写入 num 方法,和父类中的方法重名,这样就会覆盖父类的 num 方法

class Animate {
	constructor() {
	    // 默认返回实例对象 this
	}
	num() {
	    console.log('我是父类的num方法')
	}
}

class Dog extends Animate {
    constructor() {
        super()
    }
    num() {
        console.log('我是子类的num方法')
    }
}
var dog = new Dog()
dog.num()     //  我是子类的num方法
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

    如果不想覆盖而是想引用父类的 num 方法,那么就在子类的 num 方法中通过 super 来调用父类的 num 方法,super.num()

class Dog extends Animate {
    constructor() {
        super()
    }
    num() {
    	super.num()  //  调用父类的 num() 方法
        console.log('我是子类的num方法')
    }
}
var dog = new Dog()
dog.num()     

//  我是父类的num方法
//  我是子类的num方法
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4. Object.getPrototypeOf()

    Object.getPrototypeOf方法可以用来从子类上获取父类。因此,可以使用这个方法判断,一个类是否继承了另一个类

Object.getPrototypeOf(Dog) === Animate   // true
  • 1

super 关键字

    super这个关键字,既可以当作函数使用,也可以当作对象使用

1. super作为函数使用

    super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。并且,super() 只能用在子类的构造函数之中。

class Animate {}
class Dog extends Animate {
	constructor() {
		super()
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

    注意: super 虽然代表了父类 Animate 的构造函数,但是返回的是子类 Dog 的实例,即 super 内部的 this 指的是子类 Dog 的实例,因此 super() 在这里相当于Animate.prototype.constructor.call (this)

2. super作为对象使用

    super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

class Animate {
	constructor() {
		this.x = 2
		this.fn = function() {
			console.log('我是父类实例的方法')
		}
	}
	num() {
		console.log('我是父类的num方法')
	}
}
class Dog extends Animate {
	constructor() {
		super()
	}
	toString() {
    	super.num()   //  调用父类的 num() 方法
    	console.log(super.x)  
        console.log(super.fn) 
        console.log(this.x)
        this.fn()  
	}
}
var dog = new Dog()
dog.toString()

//  我是父类的num方法   
//  undefined
//  undefined
//  2
//  我是父类实例的方法
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

    子类 Dog 当中的 super.num(),就是将 super 当作一个对象使用。这时,super 在普通方法之中,指向Animate.prototype,所以 super.num() 就相当于 Animate.prototype.num()

    注意: 由于super指向父类的原型对象,所以定义在父类 Animate 实例上的方法或属性,是无法通过 super 调用的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/78747
推荐阅读
相关标签
  

闽ICP备14008679号