1.原型链继承
function Person(name, age) {
this.name = name;
this.age = age;
}
function Student(study) {
this.study = study;
}
// 现在想让学生也拥有姓名和年龄
// 第一种方法 原型链继承
Student.prototype = new Person("李四", 20);
// 学生也是人,也有姓名,年龄,学生有一个单独的属性--->学习
var p1 = new Person("张三", 18);
var p2 = new Student("学js");
var p3 = new Student("学js");
console.log(p1.name)
console.log(p2.study, p2.name,p2.age,p3.name)
问题:
1.来自Person构造函数的所有属性和方法被子类实例所继承
2.创建子类(Student)构造函数时无法向父类构造函数传递属性
3.想要给子类添加属性和方法必须要放到子类构造函数原型指向父类构造函数原型之前添加
理解即下图:(纯粹个人理解 有错误请大佬们指出)
2.构造函数继承
// 通过call()让Student借用 Person的属性
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.catch=function(){
console.log("吃东西不喽")
}
function Student(name,age,study) {
Person.call(this,name,age);//关键的一句 理解为Person.call(呼叫)(this,此时this指向Student构造函数,name,age) Student呼叫 Person的name和age属性
this.study = study;
}
var p1 = new Person("张三", 18);
var p2 = new Student("李四",20,"学js");
var p3 = new Student("王五",20,"学技术");
console.log(p1,p2,p3)
输入结果:
问题:
1.借用父类构造函数来增强子类构造函数,使用call()继承多个属性
2.创建子实例对象时可以传递参数(学生可以拥有自己的姓名,年龄)
2.无法继承父类的方法
3.混合继承(原型链继承+构造函数继承(也叫借用函数继承))
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.catch=function(){
console.log("吃东西不喽")
}
function Student(name,age,study) {
// 通过call()让Student借用 Person的属性
Person.call(this,name,age);
this.study = study;
}
Student.prototype=new Person();
// 给学生原型添加方法要放在改变原型指向后
Student.prototype.eat=function(){
console.log("玛德,该下班吃饭了")
}
var p1 = new Person("张三", 18);
var p2 = new Student("李四",20,"学js");
var p3 = new Student("王五",20,"学技术");
console.log(p2,p3)
p2.catch();
p2.eat();
问题:
1.子类构造函数创建实例时能传递参数
2.可以继承父类构造函数原型中的方法
4.对象冒充(改变this指向)
function Person(name, age) {
this.name = name;
this.age = age;
this.catch=function(){
console.log("吃东西")
}
}
function Student(name,age) {
this.nweName=Person;
this.nweName(name,age);
delete this.nweName;
}
var p2 = new Student("李四",20,);
var p3 = new Student("王五",20,"学技术");
p2.catch()
console.log(p2,p3)
问题:
1.不能继承父类构造函数原型上的方法
2.可以继承父类构造函数内的属性和方法
解释: 通过在Student中创建私有属性 nweNmae,并且把Person作为变量赋值给newNmae,所以在这里this.newName是Person构造函数,this.newName(name,age)调用Person构造函数初始化属性。delet删除Student中的newName属性。
在Student创建实例时,在Student构造函数中把this传递给了Person构造函数,并且把属性放在Person构造函数内初始化。
5:拷贝继承
(1)直接赋值
var obj={
name:"李四",
age:20
}
var obj2=obj
console.log(obj2)
引用类型放在堆中他们是地址,在这里新创建一个变量obj2并且把obj的地址赋值给了obj2。所以,obj2中也有obj中的属性和方法
(2)开辟新空间使用枚举法
function Person(){
}
Person.prototype.nage="李四";
Person.prototype.age=18;
var obj={};
for(var key in Person.prototype){
obj[key]=Person.prototype[key]
}
console.log(obj)