继承
继承的方式
1.构造函数继承
- 可以使用apply和call改变this指向来继承父类的方法和属性,在子类的函数中通过【父类.call/apply(this,参数1,参数2。。。)】来继承父类
- call和apply的第一个参数为函数运行的作用域【this】, 第一个参数写的什么,那么函数的this指向由此决定, Person.call(this,name,age)写在Male中,this指的是Male,所以Person中方法的作用域改为Male
- 【我的理解是,原本子类中没有父类的方法和属性,但是父类中有,所以我们换掉父类中的this,同样是this,但是经过call/apply后父类中的this已经是子类的this了(因为Person.call(this,name,age)写在Male中,this指的是Male),这样子类才拥有了父类的方法和属性】
function Person(name, age) {
this.name=name;
this.age=age;
this.say = function() {
console.log(this.name + "现在" + this.age);
};
console.log(this) //Male {name: "张云雷", age: 26, say: ƒ}
}
function Male(name,age){
console.log(this) // 没有call函数之前打印出当前的函数 Male{}
Person.call(this,name,age)
console.log(this) //Male {name: "张云雷", age: 26, say: ƒ}
console.log(this.name,this.age)
}
let male= new Male('张云雷',26);
比如:function sum(a,b){
conole.log(this.a+this.b)
}
let obj={
a:1,
b:2
}
sum.call(obj)
相当于:
let obj={
a:1,
b:2,
sum:function(){
console.log(this.a+this.b)
}
}
call改变了sum函数中原本指向window的this,现在指向call函数的第一个参数
- 子类直接复制父类的原型对象
关于对原型对象的理解
function Person(){
}
Person.prototype.name='jhon';
Person.prototype.age='20';
//直接在原型链上添加方法
Person.prototype.sayhello=function(){
document.write(this.name);
}
function Male(){
}
// 此时是将Person函数中的prototype的地址复制给Male
// 所以当Male中的属性改变时,父类中的属性也会改变
Male.prototype=Person.prototype;
Male.prototype.sex='nan';
var male=new Male();
male.sayhello();//jhon
var p=new Person();
// 父类中没有sex属性,但是因为Male中的属性发生了
// 改变,Male复制了父类的地址,所以也改变了父类的属性
console.log(p.sex);//nan
- 因为第二种方法的bug,进行改进
// 遍历之后就可以改变子类的属性而不影响父类
// 因为我们只是复制了父类属性的内容
for(var i in Person.prototype){
Male.prototype[i]=Person.prototype[i]
}
- 原型链继承:因为call无法继承直接在函数原型对象上定义的方法,通过创建的是实例对象对函数的原型对象进行赋值继承
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function () {
// console.log(this.name + "现在" + this.age);
console.log(111)
};
}
//在原型对象上直接定义方法
Person.prototype.show=function(){
console.log(111)
}
function Male(name, age) {
}
let male=new Male('周九良',20)
male.show()// 显示male.show is not a function
Male.prototype=new Person()
let newMale=new Male('孟鹤堂',20)
console.log(newMale.name)//孟鹤堂
- 最好使用组合继承,call和原型对象继承结合使用
以上,来自笔记。