2013-05-16 119 views
2
var a = function(){ 
    this.sayFoo = function(){ 
     console.log('foo'); 
    }; 
} 

var b = function(){ 
    console.log(this.prototype); //undefined 
    this.sayBar = function(){ 
     console.log('bar'); 
    }; 
} 

b.prototype = new a(); 

var bInst = new b(); 

bInst.sayFoo(); 
bInst.sayBar(); 

console.log(b.prototype); //a {sayFoo: function} 

http://jsfiddle.net/KbBny/1/內部構造函數原型設置

如何添加sayBarb原型構造函數裏面?

b.prototype = new a();是否覆蓋原型,或合併ba的?

+1

原型的整體思路是,你把它定義* *外的構造,而不是內部。 –

+0

閱讀此:http://stackoverflow.com/a/8096017/783743 –

回答

1

是否b.prototype = new a();覆蓋原型,或合併B的用的?

它用新的a實例覆蓋它;沒有合併(例如,您需要更新b.prototype.constructor屬性)。這就是爲什麼你在這一行之後添加所有屬性到b.prototype。然而,實際上你不希望創建一個實例,但剛剛成立的原型鏈中正確:

b.prototype = Object.create(a.prototype); 

如何添加sayBar給函數構造函數中的B原型?

你不應該把它添加到原型,因爲它不是一個原型(共享)方法 - 它的實例,具體到每一個a實例(至少是應該的,否則你會把它放在a.prototype然後它被上面的線覆蓋)。要獲得所有b實例的實例方法,以及,你使用

var b = function(){ 
    a.call(this); // invoke the `a` constructor on this instance 
}; 
+0

嗯,不知道我是否在跟蹤你的最後一部分。如果我在b construcor函數中使用'this.sayBar = ...',它必須爲每個b的實例重新定義,對吧?將它添加到原型不是更好嗎? – Johan

+1

@ alex23不,函數總是不在原型中。 – Alnitak

+0

@ alex23然後請解釋爲什麼我不在控制檯中看到兩種方法:http://jsfiddle.net/KbBny/2/ – Johan

2

您沒有使用正確的繼承模式。

用途:

b.prototype = Object.create(a.prototype); 

在你的情況,你正在執行一個簡單的覆蓋,您沒有正確建立繼承。 Object.create是ES5,但你可以用這種填充工具:

的Object.create

if (!Object.create) { 
    Object.create = function (o) { 
     if (arguments.length > 1) { 
      throw new Error('Object.create implementation only accepts the first parameter.'); 
     } 
     function F() {} 
     F.prototype = o; 
     return new F(); 
    }; 
} 

訪問原型

您不能訪問prototype定義塊內。你有一個this參考。

var b = function() { 
    a.call(this); 
    b.prototype.doSomething = function() {console.log("b");}; 
}; 
b.prototype = Object.create(a.prototype); 

DEMO

+0

這是否合併原型?那麼瀏覽器如何支持'Object.create'? – Johan

+0

謝謝,是否足以包含'Object.create'的源代碼以便在舊版瀏覽器中支持它?還是它依賴於其他功能? – Johan

+0

@Johan https://developer.mozilla。org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create#Polyfill –