2012-08-07 50 views
3

我想知道這兩種方法有什麼區別。他們都工作,但我不明白,如果第二種方法可能有不良影響?JavaScript:在哪裏放置原型功能

// A. Putting a prototype method outside the function declaration (what I would normally do) 
var Cat = function(){ 
} 

Cat.prototype.eat = function(){ 
    // implementation 
} 

// B. Putting a prototype method inside the function declaration (it works too but the scoping seems different) 
var Cat = function(){ 

    Cat.prototype.eat = function(){ 
     // implementation 
    } 
} 

回答

1

每個對象都有一個原型。原型繼承允許你指定任意一個全新的原型(類似於經典的繼承):

function Animal() { 
    this.numLegs = 4; 
} 
function Cat() { 
    // Implementation 
} 
Cat.prototype = new Animal(); 

var kitten = new Cat(); 
console.log(kitten.numLegs); // 4 

或者直接添加變量和方法,以當前類的原型:

function Cat() { 
    // Implementation 
} 
Cat.prototype.numLegs = 4; 

var kitten = new Cat(); 
console.log(kitten.numLegs); // 4 

你第二個示例簡單地在每次啓動Cat類時將Cat函數的eat函數重新分配給Cat原型,該函數無用,但不會佔用任何內存,因爲它只是覆蓋舊值。

爲什麼這很有用?請記住,函數是對象。對於您的類的每個實例,在該類中定義的每個變量和函數都會佔用它自己的內存。使用原型繼承,您可以共享常用方法,從而不會佔用每個實例的額外內存。

爲什麼這不是有用的?您無權訪問私有變量。

請記住,這是不一樣的事,作爲一個靜態方法,它可以聲明爲:

Cat.feed = function(kittens) { 
    for (var kitten in kittens) { 
     kitten.eat(); 
    } 
}; 
+0

感謝您的所有意見。我現在記得爲什麼我擺在這首先:我找不到從原型函數訪問私有變量的方法。我現在明白你不應該那樣做,因爲私有變量只能從創建它們的範圍訪問。如果您需要訪問原型中的變量,則應該使用'this'關鍵字而不是'var'來聲明公共變量, – ChrisRich 2012-08-07 23:55:57

4

你可能想要做的第一個例子。兩者都做同樣的事情,雖然技術上第二個功能可以訪問Cat的「私有」變量。不過,如果你想這樣做,做了正確的方法是使用this

var Cat = function(){ 
    var a = 'hi'; 

    this.eat = function() { 
     alert(a); // Exists! 
    } 
} 

請記住,與上面的例子中,或與您的原「B」例如,吃的功能將不存在直到你用new Cat()實例化一個新的Cat。意思是,如果你只想在功能本身上調用Cat.eat(),就像實用方法一樣,那麼prototype的第一個例子就是要走的路。

+0

另外,2擋例子搞亂了可怕的,當你創建幾個'貓'因爲他們所有的'吃'方法都會訪問最後一個'貓'的「私人」變種。 – Vatev 2012-08-07 07:46:15

+1

哈哈,我甚至沒有考慮過。這將會導致一些殺手級的調試。 – 2012-08-07 07:57:46

+0

@Vatev - 你不能在它們聲明的函數之外訪問「私有」變量。使用'this'聲明的變量是公共的,並且可以在構造函數和原型方法中以'this.var'方式訪問。 – Wex 2012-08-07 08:02:20