繼承:就是讓一個(gè)對(duì)象可以具有另一個(gè)對(duì)象的特征
一個(gè)對(duì)象訪問到另一個(gè)對(duì)象的屬性
訪問一個(gè)對(duì)象的屬性或方法時(shí),先在當(dāng)前對(duì)象上找,找不到,就去這個(gè)對(duì)象的原型(對(duì)象)上找,找到了就能訪問。
原型繼承
將父類的對(duì)象賦值給子類的原型
function Person(){
? ? this.eat = "能吃";
? ? this.pao = "能跑";
}
var person= new Person();//實(shí)例化人類,得到人類對(duì)象
function Man(){
? ? this.liqi = "特別大";
? ? this.sport = "比較擅長(zhǎng)"
}
Man.prototype = person;//將男人類的原型對(duì)象賦值為人類對(duì)象
function Woman(){
? ? this.gao = "不高";
}
Woman.prototype = person;//將女人類的原型賦值為人類對(duì)象
var xiaomei = new Woman();
console.log(xiaomei.eat);//訪問女人對(duì)象的eat屬性 能吃
var ahao = new Man();//訪問男人對(duì)象的eat屬性 能吃
console.log(ahao.eat);
上下文調(diào)用函數(shù)
把父類構(gòu)造函數(shù)體借用過來使用
? 上下文調(diào)用模式:
call
apply
bind
? 共同點(diǎn)就是能改變this的指向
? ? call怎么改變?
? ? ? 可以調(diào)用函數(shù),順便將里面的this改成目標(biāo)參數(shù)
function Animal(){
? ? this.eat = "能吃";
? ? this.pao = "能跑";
}
Animal.prototype.dong = function(){
? ? console.log("能動(dòng)");
}
function Cat(){
? ? Animal.call(this); //這里的this指的是new Cat 的對(duì)象c
? ? //將Animal中的this改成了c
? ? //將Animal進(jìn)行調(diào)用 執(zhí)行這里的代碼 this.eat? ====>? d.eat
? ? ? //this.pao? ===>? c.pao
? ? this.name = "貓";
}
var c = new Cat();
console.log(c);
//上下問調(diào)用的缺點(diǎn):不能繼承父類原型上的方法,
//所以在借用函數(shù)繼承的基礎(chǔ)上再進(jìn)行原型的方式繼承
組合繼承
解決上下文調(diào)用模式的缺點(diǎn)
組合繼承:使用上下文調(diào)用模式+原型來繼承
function Animal(){
? ? this.eat = "能吃";
? ? this.pao = "能跑";
}
Animal.prototype.dong = function(){
? ? console.log("能動(dòng)");
}
function Cat(){
? ? // 使用上下文調(diào)用,模式來繼承
? ? Animal.apply(this);
? ? this.name = "貓";
}
//使用原型來繼承
Cat.prototype = new Animal();
// 其實(shí)就沒有必要讓new Animal作為原型了,因?yàn)樵蹅冎恍枰狝nimal的方法,
//這個(gè)方法不在Animal上,在原型上,
//所以可以將Animal的原型作為自己的原型(前提:就是Animal沒什么用了)
Cat.prototype.constructor = Cat;
var c = new Cat();
console.log(c);
c.dong();
var a = new Animal();
console.log(a);
es6中的繼承
class Animal{ // 父類
? ? ? constructor(name){
? ? ? ? ? this.eat = "能吃";
? ? ? ? ? this.pro = "能跑"
? ? ? ? ? this.name = name;
? ? ? }
? ? ? dong(){
? ? ? ? ? console.log("能動(dòng)");
? ? ? }
? }
? class Rubbit extends Animal{ //子類-extends關(guān)鍵字并不能執(zhí)行父類的constructor
? ? ? constructor(name){
// 如果父類有constructor,子類這里(constructor里面)必須調(diào)用一個(gè)叫做super的方法
? ? ? ? ? super(name); // 這是在執(zhí)行父類的constructor
? ? ? ? ? this.leg = "4條";
? ? ? }
? ? ? sport(){
? ? ? ? ? console.log("跑的特別快");
? ? ? }
? }
? var r = new Rubbit("兔子");
? console.log(r);
? //exteds 是es6提供的用來繼承的語(yǔ)法
? //function Person(name){
? ? //this.name = name;
? ? //this.eat = "能吃"
? ? //}
? ? //class Man extends Person{
? ? ? //? constructor(name){
? ? ? ? //? ? super(name);
? ? ? //? }
? ? //}
? ? //var m = new Man("豚豚");
? ? //console.log(m);
語(yǔ)法:
class Animal{
? ? //如果在實(shí)例化需要傳遞參數(shù)的話,就在這個(gè)類中,寫一個(gè)函數(shù),
? ? //名字必須是constructor
}
var animal = new Animal();
console.log(animal); // Animal {}
class 子類 extends 父類{
?constructor(){
super();
}
}
例:
class Animal{
? ? constructor(name){
? ? ? ? this.name = name;
? ? }
? ? dong(){
? ? ? ? console.log("能動(dòng)");
? ? }
}
class Dog extends Animal{
? ? constructor(name){
? ? ? ? super(name);
? ? ? ? this.jiao = "汪汪";
? ? }
}
var ergou = new Dog("狗");
console.log(ergou); // Dog {name: "狗", jiao: "汪汪"}
ergou.dong(); // 能動(dòng)
總結(jié):
? ? 繼承就是讓一個(gè)類擁有另一個(gè)類的屬性和方法。