2014-02-18 86 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实际上只是一个面向对象的构造,它在哲学上只是使代码更优雅,所以在这种情况下,我认为这就是所有的原型。
相关问题