原型鏈繼承和借用建構函式繼承。這兩種模式都存在各自的缺點,所以組合繼承是將二者結合到一起,從而發揮二者之長。即在繼承過程中,既可以保證每個例項都有它自己的屬性,又能做到對一些屬性和方法的復用.
function
person(name)
person.prototype.say*** = function()
person.prototype.sayname = function()
function
animal(name)
animal.prototype = object.create(person.prototype)
//因為 動物性別不是男女 所以我們需要改寫 say***
animal.prototype.say*** = function()
var dog = new animal("狗")
dog.sayname()
dog.say***() 複製**
結果如下:
為什麼animal.prototype = object.create(person.prototype)
而不是animal.prototype = new person()
function
person(name)
person.prototype.say*** = function()
var person1 = object.create(person);
console.log(person1.say***) // undefined
console.log(person1.name) // "person"
複製**
為什麼會出現這樣的結果?
首先看看object.create
到底幹了啥?
object.create = function (o) ;
f.prototype = o;
return
new f();
};複製**
通過**我們知道
1)因為object.create內部的新物件是new f()建立的,跟person建構函式沒有關係,所以不能訪問到person中的屬性
2)呼叫person1.say*** 時首先判斷person1物件有沒有相應的方法,如果沒有,則查詢person1的原型鏈上有沒有該方法,person1的原型屬性是person建構函式(可以通過person1.__proto__來證明), 建構函式沒有say***方法,自然也就是undefined了。
3) return new f()後f被銷毀,object.create建立物件是建立乙個擁有指定原型和若干個指定屬性的物件,也就是說可以任意指定原型,甚至是null。所以在上述中像o.prototype新增屬性不被繼承
如果換成object.create(person.prototype)
; 會是什麼情況呢?
function
person(name)
person.prototype.say*** = function()
var person1 = object.create(person.prototype);
console.log(person1.say***)
console.log(person1.name) 複製**
輸出結果如下:
new object()方法的實質是,使用引用型別object的建構函式建立了乙個新的例項,這個例項擁有object預設的方法如tostring、tolocalestring等。經歷了以下四個步驟:
1) 建立乙個新物件;
2) 將建構函式的作用域賦給新物件(因此 this 就指向了這個新物件) ;
3) 執行建構函式中的**(為這個新物件新增屬性) ;
4) 返回新物件。
當我們執行:
function
person()
var person1 = new person();
複製**
實際上是按照如下過程執行的:
var person1 = {};
person1.__proto__ = person.prototype;
person.call(person1);複製**
其實在new 的過程中 我們執行了建構函式的方法,而在create 過程中我們並沒有執行建構函式的方法
function
create(obj)
function
createprototype()
createprototype.prototype = obj;
return
new createprototype();
}複製**
使用:
animal.prototype = create(person.prototype)
關於C 中的虛擬繼承的一些總結
1.為什麼要引入虛擬繼承 虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。如 類d繼承自類b1 b2,而類b1 b2都繼承自類a,因此在類d中兩次出現類a中的變數和函式。為了節省記憶體空間,可以將b1 b2對a的繼承定義為虛擬繼承,而a就成了虛擬基類。實現的 如下 class a ...
關於C 中的虛擬繼承的一些總結
關於c 中的虛擬繼承的一些總結 1.為什麼要引入虛擬繼承 虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。如 類d繼承自類b1 b2,而類b1 b2都繼承自類a,因此在類d中兩次出現類a中的變數和函式。為了節省記憶體空間,可以將b1 b2對a的繼承定義為虛擬繼承,而a就成了虛擬基類...
關於C 中的虛擬繼承的一些總結
1.為什麼要引入虛擬繼承 虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。如 類d繼承自類b1 b2,而類b1 b2都繼承自類a,因此在類d中兩次出現類a中的變數和函式。為了節省記憶體空間,可以將b1 b2對a的繼承定義為虛擬繼承,而a就成了虛擬基類。實現的 如下 class a ...