原型繼承:
// '父'建構函式
function father() {
this.name = 'foo';
this.family = ['jack','tom','james'];
father.prototype.sayname = function () {
console.log(this.name);
father.prototype.sayfamily = function () {
// '子'建構函式
function child() {
// 實現繼承
child.prototype = new father();
// 看看繼承之後的效果
let childinstance1 = new child();
childinstance1.sayname(); // 'foo'
childinstance1.sayfamily(); // ['jack','tom','james']
通過將子建構函式的原型設定為父建構函式例項的方法實現了繼承,這就是原型鏈繼承。在這個例子中,子建構函式的例項本身是沒有 name 和 family 屬性的,這兩個屬性都是通過原型鏈在子建構函式的原型上找到的,而子建構函式的原型來自于父建構函式的乙個例項。 子建構函式的例項本身也是沒有 sayname 和 sayfamily 方法的,沿著原型鏈查詢,子建構函式的原型中也沒有這兩個方法,再向上查詢,這兩個方法來自與父建構函式的原型上。
原型鏈繼承的問題:
通過這種繼承方法,有乙個比較明顯的問題,我們知道,引用型別的原型屬性會被所有的例項共享,那麼在上面的例子中,由於子建構函式的原型是父建構函式的例項,所以 family 屬性(陣列是引用型別)會被子建構函式的所有例項共享。也就是說,當我們修改了子建構函式乙個例項上的 family 屬性時,會對子建構函式原型上的該屬性直接產生影響,從而影響到子建構函式的全部例項。
// 修改childinstance2的屬性值,看看會有什麼影響
let childinstance2 = new child();
childinstance2.name = 'bar';
childinstance2.family.push('curry');
childinstance1.sayname(); // 'foo'
childinstance1.sayfamily(); // ['jack','tom','james','curry']
childinstance2.sayname(); // 'bar'
childinstance2.sayfamily(); // ['jack','tom','james','curry']
我們看到,修改了 childinstance2 的 name 屬性(字串是基礎型別),不會對其他例項產生影響,但是當我們修改了 family 屬性時,就會造成 childinstance1 的 family 屬性也被修改了。這顯然會帶來很多的麻煩。
組合繼承:思路是通過原型鏈實現對原型屬性和方法的繼承,但是利用建構函式實現對例項屬性的繼承,避免屬性被共享。
// '父'建構函式
function father() {
this.family = ['jack','tom','james'];
father.prototype.sayfamily = function () {
console.log(this.family);
// '子'建構函式
// 這裡利用建構函式把父建構函式的屬性直接放到子建構函式屬性中
function child() {
father.call(this);
// 實現繼承
child.prototype = new father();
// 看看繼承之後的效果
let childinstance1 = new child();
childinstance1.sayfamily(); // ['jack','tom','james']
// 修改subinstance2的屬性值,看看會有什麼影響
let childinstance2 = new child();
childinstance2.family.push('curry');
childinstance1.sayfamily(); // ['jack','tom','james']
childinstance2.sayfamily(); // ['jack','tom','james','curry']
採用組合繼承,子建構函式創造出來的例項本身就有 family 屬性(建構函式具有的屬性和方法都在例項本身),不必再通過原型鏈向原型查詢,也就避免了屬性被共享的問題。
js繼承,原型鏈繼承
1 乙個型別的物件能夠訪問另外乙個型別的屬性和方法 2 類與類之間的關係 類就是眾多例項共有的屬性和方法的乙個抽象 function animal name animal.prototype.say function function dog 把子類的原型指向父類的例項 dog.prototype ...
11 03 繼承,原型鏈 組合繼承
1.介面繼承在ecmascript中是不可能的,因此實現繼承是ecmascript唯一支援的繼承方式,因此顯示中主要是通過原型鏈繼承。subtype的原型指向supertype的原型,因此繼承它的所有原型上的屬性和方法,若例項把所繼承來的方法遮避了,相當於建構函式下的方法被重寫了。2.原型和繼承的關...
js 原型鏈繼承
建構函式的prototype的 proto 預設指向object.prototype,是繼承object。function animal age animal.prototype.getage function animal.prototype.eat function function dog n...