參考資料
不要講什麼設計模式 , 看得老子腦袋昏 , 智商欠費 , 仍是簡單點 , 方案 , 繼承 , 就完事了html
// 首先咱們得有個父類
// 這個父類也很簡單
function Human(name) {
this.name = name || '肥宅' // 有參就取參 , 沒參就叫肥宅
}
Human.prototype.drink = function(drinks) {
console.log(this.name + '正在喝' + (drinks || '可樂'));
}
複製代碼
OK, 咱們如今有了一個父類, 先來看一個最簡單的繼承設計模式
直接把父類的實例做爲子類的原型函數
// 先寫個空類
function Jianren(){}
Jianren.prototype = new Human()
// new個實例看看
var haidong = new Jianren();
console.log(haidong.name); //'肥宅'
console.log(haidong.drink()); //'haidong正在喝可樂'
複製代碼
對於這個繼承, 歸納爲子類的原型鏈綁定父類的實例實現繼承性能
缺陷ui
複製父類屬性this
function Jianren(){
Human.call(this);// 把父類寫進子類構造函數內部, 調用call把子類的this傳進去改變this的指向作到複製父類屬性
this.age = 22
}
複製代碼
在子類內部添加一個屬性, 該屬性爲父類的實例spa
function Jianren(name){
var ren = new Human();// 注意這裏是否是this
ren.name = name || 'haidong';
return ren;
}
複製代碼
function Jianren(name){
var ren = new Human()
for(var r in ren) {
Cat.prototype[r] = ren[r] // 該處r是key, 應該用Object[key]的形式賦值和訪問
}
Jianren.prototype.name = name || 'haidong'
}
複製代碼
上面的繼承主要是幫助理解, 或有時暴力快速解決小問題時使用 .prototype
推薦一, 組合繼承設計
子類的原型指向父類實例,該父類實例又可向上原型查找訪問,修正後constructor指向子類自身code
function Jianren(name) {
Human.call(this) //第一步拷貝屬性
this.name = name || 'haidong'
}
Jianren.prototype = new Human() //第二步, 原型指向父類實例
Jianren.prototype.constructor = Jianren //第三步, 修正constructor指向
複製代碼
推薦二, 寄生組合繼承
// 有點複雜
function Jianren(name) {
Human.call(this) //第一步拷貝屬性
this.name = name || 'haidong'
}
(function() { //來個匿名當即執行函數
function J() {}// 建立一箇中間類, 空, 什麼都沒有
J.prototype = Human.prototype //第二步中間類原型指向父類原型
Jianren.prototype = new J() //子類原型賦值爲中間類的實例,往上查找,指向了父類的原型
})()
Jianren.prototype.constructor = Jianren //修正子類constructor指向
複製代碼
與上面的組合繼承相比, 第一步拷貝 和 第二步中間類(空類)不會重複有Human的屬性, 略微複雜, 能夠忽略不計, 完美方式