1.原型链继承
通过改变原型指向实现继承
缺陷:改变原型指向的同时继承,直接初始化了属性,继承过来的属性的值都是一样的
解决方案:继承的时候,不改变原型的指向,直接调用父级的构造函数的方式来为属性赋值就可以
// 人的构造函数
function Person(name){
this.name=name;
}
// 人的原型方法
Person.prototype.eat=function(){
console.log("人在吃东西");
};
// 学生的构造函数
function Student(score){
this.score=score;
}
// 改变了学生的原型的指向
Student.prototype=new Person("小明");
// 学生的原型方法
Student.prototype.study=function(){
console.log("学生在学习");
};
// 实例化对象
let stu=new Student(99);
console.log(stu.name);
stu.eat();
// 下面是学生的专有属性
console.log(stu.sex);
stu.study();
2.借用构造函数继承
把要继承的父级的函数拿过来,使用下就可以,解决了属性继承,并且值不重复问题
缺陷:父级类别中的方法不用继承
// 人的构造函数
function Person(name,age,sex,weight){
this.name=name;
this.age=age;
this.sex=sex;
this.weight=weight;
}
Person.prototype.saiHi=function(){
console.log("您好啊");
}
// 学生的构造函数
function Student(name,age,sex,weight,score){
// 借用构造函数
Person.call(this,name,age,sex,weight);
this.score=score;
}
let stu1=new Student("小明",10,"男","45kg","100");
console.log(stu1.name,stu1.age,stu1.sex,stu1.weight,stu1.score);
3.组合继承
原型链继承+借用构造函数继承,既能解决属性问题,又能解决方法问题
function Person(name, age, sex, weight) {
this.name = name;
this.age = age;
this.sex = sex;
this.weight = weight;
}
Person.prototype.saiHi = function () {
console.log("您好啊");
}
// 学生的构造函数
function Student(name, age, sex, weight, score) {
// 借用构造函数
Person.call(this, name, age, sex, weight);
this.score = score;
}
Student.prototype=new Person();
Student.prototype.study = function () {
console.log("学生在学习");
};
let stu = new Student("小明", 10, "男", "45kg","100");
console.log(stu);
4.原型式继承
Object.create()
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
let obj={
name:"小糊涂",
age:20,
sleep:function(){
console.log("睡了睡了");
}
}
// 原型式继承函数
function createObject(o){
let newObj={};
Object.setPrototypeOf(newObj,o);
return newObj;
}
function createObject2(o){
function Fn(){};
Fn.prototype=o;
let newObj=new Fn();
return newObj;
}
// let info=createObject2(obj);
let info=Object.create(obj);
console.log(info);
console.log(info.__proto__);
5.寄生式继承
就是给原型式继承外面套了个壳子
let personObj={
running:function(){
console.log("running~");
}
}
function createStudent(obj,name){
let stu=Object.create(obj);
stu.name=name;
stu.study=function(){
console.log("study~");
}
return stu;
}
let stuObj1=createStudent(personObj,"why");
let stuObj2=createStudent(personObj,"kobe");
let stuObj3=createStudent(personObj,"james");
console.log(stuObj1);
console.log(stuObj2);
console.log(stuObj3);
6.寄生组合式继承
最理想的继承方法
// 封装寄生组合式继承
function createObject(o){
function Fn(){}
Fn.prototype=o;
return new Fn();
}
function inheritPrototype(subType, superType) {
subType.prototype = createObject(superType.prototype);
Object.defineProperty(subType.prototype, "constructor", {
enumerable: false,
configurable: true,
writable: true,
value: subType
});
}
function Person(name, age, sex, weight) {
this.name = name;
this.age = age;
this.sex = sex;
this.weight = weight;
}
Person.prototype.saiHi = function () {
console.log("您好啊");
}
// 学生的构造函数
function Student(name, age, sex, weight, score) {
// 借用构造函数
Person.call(this, name, age, sex, weight);
this.score = score;
}
inheritPrototype(Student, Person);
Student.prototype.study = function () {
console.log("学生在学习");
};
let stu = new Student("小明", 10, "男", "45kg", "100");
console.log(stu);
console.log(stu.name, stu.age, stu.sex, stu.weight, stu.score);
stu.saiHi();
stu.study();
继续努力学习,每日进步一点点!!!