核心:子構造函數的原型指向父構造函數的實例bash
每一個構造函數都有一個原型對象,原型對象中都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。當原型對象等於另一個類型的實例即繼承。調用某個方法或者屬性的步驟app
a.搜索實例函數
b.搜索原型性能
c.搜索父類原型this
function Animal() {
this.name = "animal";
this.arrt = [1, 2]
}
Animal.prototype = {
sayName: function () {
alert(this.name);
}
}
function Dog() {
this.color = "灰色"
}
Dog.prototype = new Animal();
Dog.prototype.sayColor = function () {
alert(this.color);
}
var dog = new Dog();
var dog1 = new Dog();
console.log(dog);
dog.arrt.push(5);
console.log(dog1);
dog.sayColor();
dog.sayName();
複製代碼
能夠本身打印一下,看一下結果spa
優勢1.很是純粹的繼承關係,實例是子類的實例,也是父類的實例prototype
2.父類新增原型方法/原型屬性,子類都能訪問到指針
3.簡單,易於實現code
缺點cdn
1.包含引用類型值的原型屬性會被全部實例共享,這會致使對一個實例的修改會影響另外一個實例。
2.在建立子類型的實例時,不能向超類型的構造函數中傳遞參數。因爲這兩個問題的存在,實踐中不多單獨使用原型鏈。
也稱 "僞造對象" 或 "經典繼承",在子類型構造函數的內部調用超類型構造函數。函數不過是在特定環境中執行代碼的對象,所以經過apply(),call()方法能夠在(未來)新建對象上執行構造函數,即 在子類型對象上執行父類型函數中定義的全部對象初始化的代碼。結果每一個子類實例中都具備了父類型中的屬性以及方法
function Animal(name){
this.name = name;
this.colors = ["red","gray"];
}
function Dog(name){
//繼承了Animal
Animal.call(this,"mary");//在子類型構造函數的內部調用超類型構造函數
this.color = "gray";
}
Animal.prototype.sayName = function(){
alert(this.name);
}
var dog = new Dog();
var dog1=new Dog();
dog.colors.push("hhh");
console.log(dog.colors);//red gray hhh
console.log(dog1.colors);//red gray
Animal.prototype.swif="hua";
console.log(dog.swif);//undefined
var animal = new Animal();
console.log(animal); //若是將函數定義在構造函數中,函數複用無從談起
dog.sayName(); //在超類型的原型中定義的方法,對於子類型而言是沒法看到的
複製代碼
優勢
1.解決了1中,子類實例共享父類引用屬性的問題
2.建立子類實例時,能夠向父類傳遞參數
3.能夠實現多繼承(call多個父類對象)
缺點
1.實例並非父類的實例,只是子類的實例
2.只能繼承父類的實例屬性和方法,不能繼承父類原型屬性/方法
3.沒法實現函數複用,每一個子類都有父類實例函數的副本,影響性能
組合繼承(combination inheritance),有時候也叫作僞經典繼承,指的是將原型鏈和借用構造函數的 技術組合到一塊,從而發揮兩者之長的一種繼承模式。其背後的思路是使用原型鏈實現對原型屬性和方 法的繼承,而經過借用構造函數來實現對實例屬性的繼承。這樣,既經過在原型上定義方法實現了函數 複用,又可以保證每一個實例都有它本身的屬性
function Animal(name){
this.name = name;
this.colors = ["red","gray"];
}
function Dog(name){
//繼承了Animal(屬性)
Animal.call(this,name);
this.color = "gray";
}
Animal.prototype.sayName = function(){
alert(this.name);
}
//繼承方法
Dog.prototype = new Animal();
Dog.prototype.constructor = Animal;
var dog = new Dog("2");
dog.colors.push("hhh");
console.log(dog);
var animal = new Animal();
console.log(animal);
dog.sayName(); //能夠調用
複製代碼
優勢
1.能夠繼承實例屬性/方法,也能夠繼承原型屬性/方法
2.既是子類的實例,也是父類的實例
3.不存在引用屬性共享問題
4.經過call繼承父類的基本屬性和引用屬性並保留能傳參的優勢
5.函數可複用
缺點
1,子類原型上有一份多餘的父類實例屬性,由於父類構造函數被調用了兩次,生成了兩份,而子類實例上的那一份屏蔽了子類原型上的。