2011-08-19 97 views
8

今天,我看到了我一生中從未見過的JavaScript模式。我無法說出使用這種模式的目的。這對我來說似乎是錯誤的,但我想保守一點。這可能是我以前從未見過的一些很棒的模式。在構造函數中定義原型方法

function Dog() { 
    Dog.prototype.bark = function() { 
     alert('woof!'); 
    } 

    this.bark = function() { 
     Dog.prototype.bark(); 
    } 

    this.bark(); 
} 

首先,我不是一個在沒有理由在構造函數內創建方法(作爲特權成員)的粉絲。每次創建實例時都會導致創建函數。其次,在這個代碼片段中,它也調用原型名稱「Dog」,而不是「this」。這讓我感到非常困惑。

任何人都知道它有什麼好處?

謝謝! Grace

+1

這似乎毫無意義。據我所知,原型對象用於將屬性添加到定義之外的對象的所有實例。由於這是在定義中,這有點多餘。 – mowwwalker

+0

我完全同意你的看法。對我來說似乎也沒有意義。 –

回答

12

這是一個非常糟糕的主意,原因很多。其中一些是:

  1. 在構造函數中向原型添加方法將導致原型方法被替換爲所有實例,每次您實例化一個新的Dog。
  2. 調用Dog.prototype.bark()意味着this將是Dog.prototype而不是您的Dog的實例,這可能導致嚴重問題。
  3. this.bark = function() { Dog.prototype.bark(); }是一些嚴重的WTF。因爲this.bark已經對原型方法進行了評估,因此不需要這樣做。如此調用它實際上會破壞天然的this值,如#2所述。

這裏是什麼是應該是:

function Dog() { 
    this.makeSound(); 
}; 

Dog.prototype.bark = function() { 
    alert('woof'); 
}; 

Dog.prototype.makeSound = function() { 
    this.bark(); 
}; 

或者,沒有原型都:

function Dog() { 
    this.bark = function() { 
    alert('woof'); 
    }; 

    this.makeSound = function() { 
    this.bark(); 
    }; 

    this.makeSound(); 
}; 

我不會在所有信任你的這個片段。

+0

#2:即使在構造函數之外初始化樹皮,也是如此 - 方法的* this *由調用設置。 #3:與#2相同(* this *將爲* Dog.prototype *),但該函數不使用* this *,因此在這種情況下不會導致問題。 – RobG

+0

你爲什麼要做'this.makeSound = function(){}'?沒有澄清,這個例子可能會引起誤解。 這不會在原型對象上得到設置,並且函數在內存中爲每個'new Dog();'實例複製。 'Dog.prototype.makeSound = function(){}'更好 – dman

2

對不起,我的答覆很遲,但如果你真的想在構造函數中添加的原型,而不是把它重新每當創建一個新實例,你可以這樣做:

function Dog() { 
    if (!Dog.prototype.bark) { 
     Dog.prototype = function() { 
      console.log('woof'); 
     } 
    } 

    this.bark(); 
} 

我仍然可能不會使用這種方法,但我有一些跨處理第三方框架(不友好的類型)時,這種方法是一個選項的實例。

相關問題