2014-02-18 84 views
0

「哦,不,」我聽到你呻吟道,「不再是這個問題」,但忍耐一分鐘。Javascript原型 - 在這種情況下有什麼優勢?

我正試圖抓住原型,並且我理解跨對象實例共享通用功能的好處。但是,在下面的情況下,我通過使用原型而不是僅僅是一個獨立的函數獲得了什麼?

我想冒了一句和隨機化每個字的位置,這樣我可以做到以下幾點:

Array.prototype.shuffle = function() { 
var i = this.length; 
if (i == 0) return this; 
while (--i) { 
    var j = Math.floor(Math.random() * (i + 1)); 
    var a = this[i]; 
    var b = this[j]; 
    this[i] = b; 
    this[j] = a; 
} 

    return this; 
}; 

function randomiser(){ 
    var s = "My name is Bob"; 
    var shuffledSentence = s.split(' ').shuffle().join(' '); 
    console.log(shuffledSentence); // "Bob My name is" 

} 

或者,我可以用一個簡單的函數調用而不是隨機化我的字符串:

function randomise(arrayToRandomise){ 
    var i = arrayToRandomise.length; 
    if (i == 0) return arrayToRandomise; 
    while (--i) { 
     var j = Math.floor(Math.random() * (i + 1)); 
     var a = arrayToRandomise[i]; 
     var b = arrayToRandomise[j]; 
     arrayToRandomise[i] = b; 
     arrayToRandomise[j] = a; 
    } 

    return arrayToRandomise; 
} 

function randomiser(){ 
    var s = "My name is Bob"; 
    var shuffledSentence = s.split(' ');//.shuffle().join(' '); 
    var myShuffledString = this.randomise(shuffledSentence).join(' '); 
    console.log(myShuffledString); // "Bob My name is" 
} 

我在這裏通過使用原型獲得了什麼(除了更優雅的代碼!)?

+0

就我個人而言,我遠離改變本地對象的原型,因爲它可以打破'for .. in',顯然它打破封裝:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/ Inheritance_and_the_prototype_chain#Bad_practice.3A_Extension_of_native_prototypes在您自己定義的對象中使用原型可以使用已知模式進行繼承,代碼重用等(OOP標準模式):http://stackoverflow.com/a/16063711/1641941 – HMR

回答

1

沒有區別或任何優點或缺點來區分它們,我去第二個解決方案,因爲我們最好不要修改JavaScript原生原型,除非(我會同意修改原生原型的唯一情況)以涵蓋一些跨瀏覽器問題。例如,如果您的瀏覽器在Array中不支持forEach,因爲您可能需要在代碼中使用它,恕我直言,將它添加到Array.prototype中並不是一件壞事。

但問題是更好的方式來做到這一點是這個代碼的方式,不會影響任何東西,當你改變Array.prototype像這樣類似:

Array.prototype.shuffle = ... 

然後如果你遍歷與陣列for(..in),你的洗牌會出現。

所以,如果我是你,我想修改本機的原型,我是這樣做的:

Object.defineProperty(Array.prototype, "shuffle", { 
    enumerable:false, 
    value:function(){ 
     //your code 
    } 
}); 

這樣一來,使用枚舉屬性,可以防止它顯示for(..in)循環起來或Object.keys()

1

我沒有那麼多說這個,但恕我直言,這裏是一些要點:

  • prototype應該最好不要延伸到原生對象,這有點類似於污染全局命名空間,但是這有點意見。
  • prototype實際上只是一個面向對象的構造,它在哲學上只是使代碼更優雅,所以在這種情況下,我認爲這就是所有的原型。
相關問題