2012-06-29 65 views
3

我來自經典的OOP背景的JavaScript,並且在理解原型時遇到了麻煩。關於Javascripts原型的幾個問題

考慮下面的代碼示例:

  1. 我怎麼會叫/ foo中執行吧?
  2. 爲什麼使用「特權」功能而不是放在原型上?
  3. 這可能是第一季度的答案,但bar1和bar2可以互相打電話嗎?

    function foo() 
        { 
         this.property = "I'm a property"; 
    
         this.privileged = function() 
         { 
          // do stuff 
         } 
        } 
    
        foo.prototype.bar = function() 
        { 
         // do stuff 
        } 
    
        foo.prototype.bar2 = function() 
        { 
         // stuff 
        } 
    

回答

4

今天有很多關於這個的FUD。

1)。簡單的用法:

var xxx = new foo(); // Create instance of object. 
xxx.privileged(); // Calls the internal closure. 
xxx.bar(); // First looks for internals, then looks to the prototype object. 

2)。這基本上創建了一個只能在實例上修改的閉包。根本不是私有的(因爲任何事物都可以通過對象實例與它交談),而是一個函數的單獨副本,其中對象的每個實例都獲得函數的新副本。你可以改變函數本身,但是你不能在全局上改變它。我不是這種創造方法的忠實粉絲。 3)。是:

foo.prototype.bar = function(){ 
    this.bar2(); 
} 

foo.prototype.bar2 = function(){ 
    this.bar(); 
} 
// Although... NEVER do both. You'll wind up in a circular chain. 

對於薰陶,我建你的小提琴,這應有助於顯示的東西是如何被稱爲: http://jsfiddle.net/7Y5QK/

+0

的的jsfiddle是優秀的!我讀了你的答案,並認爲「是的,有道理」。開始思考「但是如果......」和jsFiddle讓我全面測試。優秀。 – JonWells

1
  1. 您可以通過執行this.bar(); foo中執行酒吧,但如果你使用new foo();它只會工作,並有一個對象從foo繼承。否則,如果您只撥打foo();,則this會指向全局對象。

  2. 它本質上是一樣的東西只有你給函數內部的繼承對象的屬性和方法可以訪問你傳遞給foo的任何參數。

  3. 是的,他們可以互相呼叫,因爲功能是「懸掛」的。他們可以訪問最近的外部範圍內的所有變量和對象,以及它們的功能上下文。

實際上,您的代碼中有語法錯誤。在你分配原型的地方,你沒有創建一個函數。您的意思是:

foo.prototype.bar = function() { /* ... */ }; 
0

1.You可以像

var f = new foo();

,然後生成foo的實例調用f.bar()f.bar2()

分2 & 3已經由大衛

解釋
2

1)第一頁是有的克萊德路寶的答案:

var f = new foo(); 
f.bar(); 

2)在consturctor(特權)上編寫函數,每個實例將創建一個新的函數,如果在prototype上定義了方法,則每個實例都共享相同的prototype的方法:

var f1 = new foo(), // instance 1 
    f2 = new foo(); // instance 2 

f1.privileged === f2. privileged // -> false , every instance has different function 
f1.bar === f2.bar // -> true, every instance share the some function 

3)你可以調用bar2bar' by this.bar()',這樣的代碼:

function foo() { 
    this.property = "I'm a property"; 

    this.privileged = function() { 
     // do stuff 
    }; 
} 

foo.prototype.bar = function() { // defined a method bar 
    alert('bar called'); 
    this.bar2(); // call bar2 
}; 

foo.prototype.bar2 = function() { // defined a method bar2 
    alert('bar2 called'); 
}; 

var f = new foo(); 
f.bar(); // alert 'bar called' and 'bar2 called' 
f.bar2(); // alert 'bar2 called'