22. 继承
继承
子类继承父类中的属性和方法(目的是让子类的实例继承父类中的属性和方法)
原型继承
-
让父类中的属性和方法在子类实例的原型链上
-
子类的prototype指向父类的实例new A()
子类.prototype = new 父类();
-
特点:
- 不像其他语言中的继承一样(其他语言的继承一般是继承拷贝,也就是子类继承父类,会把父类中的属性和方法拷贝一份到子类,供子类的实例调取使用)它是把父类的原型放到子类实例的原型链上的,实例想调取这些方法,是基于
__proto__
原型链查找机制完成的 - 子类可以重写父类上的方法(这样会导致父类其他的实例也受到影响)
- 父类中私有或者共有的属性方法都会变成子类的共有属性和方法
- 不像其他语言中的继承一样(其他语言的继承一般是继承拷贝,也就是子类继承父类,会把父类中的属性和方法拷贝一份到子类,供子类的实例调取使用)它是把父类的原型放到子类实例的原型链上的,实例想调取这些方法,是基于
原型继承的缺陷:
1.一定要先实现继承关系,在为子类添加原型方法或属性
2.一旦继承关系实现,原型对象的指向便不能修改
3.无法在子类对象构造时,初始化由父类派生给子类的属性
//父类
function A(x) {
this.x=x
}
A.prototype.getX=function(){
console.log(this.x)
}
//子类
function B(x) {
this.y=y
}
//B的原型指向A的实例
B.prototype=new A()
B.prototype.constructor=B
B.prototype.getY = function(){
console.log(this.y)
}
let b1=new B(100)
console.log(b1.y)//100
b1.getX()//undefined
b1.getY()//100
ES6中extend继承(extends和super)
super关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数,必须写在子类构造方法的第一行
继承中的属性或者方法查找原则:就近原则
1.继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类
2.继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象
类里面的共有的属性和方法一定要加this使用.
//es6中继承
class A {
constructor(x){
this.x=x
}
getX(){
console.log(this.x)
}
}
class B extends A {
//子类只要继承父类,可以不写constructor,一旦写了就要在第一句话中协商super()
//不写constructor 浏览器会自动默认创建constructor(...arg){}
constructor(y) {
//把父类当做普通方法执行,给方法传递参数,让方法中的this是子类的实例
super()
this.y=y
}
getY(){
console.log(y)
}
}
借用构造方法实现"继承"
apply和call"继承"
作用:可以实现,子类对象在构造时,初始化父类派生给子类的属性
缺陷:无法继承原型对象上的属性和方法
function Human(name,id){
this.name = name;
this.id = id;
this.eat = function(){
console.log("eat");
}
}
// Human.prototype.eat = function(){
// console.log("eat");
// }
function Student(name,id,score){
//借用构造方法
Human.apply(this,[name,id]);
this.score = score;
}
let s = new Student("老王",1,100);
console.log(s.name,s.id,s.score);
s.eat();
混合继承:
不是新语法
1.通过借用构造方法(apply和call)实现属性的继承
2.通过原型继承,实现原型对象上属性和方法的继承
function Animal(name,id){
this.name = name;
this.id = id;
}
Animal.prototype.eat = function(){
console.log("Animal eat");
}
function Student(name,id,score){
//属性的继承
Animal.call(this,name,id);
this.score = score;
}
Student.prototype = new Animal();
Student.prototype.sleep = function(){
console.log("student sleep");
}
let s = new Student("laowang","123",100);
console.log(s.name,s.id,s.score);
s.eat();
s.sleep();
面试题?
typeof
和instanceof
的异同?
1.都是用来判断对象类型的关键字
2.typeof
用来判断内置基本类型number
,string
,boolean
,如果判断引用类型,
则结果全都是object
3.intanceof
判断引用类型,并且满足类型兼容性规则
intanceof
:判断引用类型的关键字
对象instanceof
类型 : 返回布尔值