Pourquoi ne puis-je pas écraser le prototype de `Array` (` Array.prototype`)?

Je définis le prototype de Array comme une instance de my , je pense que book.aa affichera "aa" , mais il affiche "undefined" , pourquoi? Merci!

  <html> <head> <title>Array Properties</title> <h2>Array Properties</h2> <script type="text/javascript"> function my() { this.aa = 'aa'; } Array.prototype = new my(); Array.prototype.bb = "bb"; var book = new Array(); book[0] = "War and Peace"; </script> </head> <body bgcolor="lightblue"> <script type="text/javascript"> document.write(book.aa+book.bb); </script> </body> </html> 

Vous ne pouvez pas attribuer à Array.prototype car le prototype est une propriété en lecture seule de Array .

Donc, lorsque vous écrivez

 Array.prototype = new my(); 

Rien ne se passe. Pour voir pourquoi, essayez

 JSON.stringify(Object.getOwnPropertyDescriptor(Array, "prototype")) 

Le résultat est

 "{"value":[],"writable":false,"enumerable":false,"configurable":false}" 

Sauf si vous êtes en mode strict, l'opération échoue silencieusement.

C'est pourquoi – et voir http://jsfiddle.net/5Ysub/ – si vous exécutez

 function my() { this.aa = 'aa'; } Array.prototype = new my(); Array.prototype.bb = "bb"; var book = new Array(); book[0] = "War and Peace"; document.write(book.aa+book.bb); 

Vous obtenez

 undefinedbb 

Le bb fonctionne car vous avez attribué le véritable Array.prototype lorsque vous avez créé et défini la propriété bb .

C'est une bonne chose que Array.prototype ne peut pas être bloqué, IMHO. 🙂

Même si vous pouviez remplacer directement Array.prototype comme cela, vous perdriez l'accès à toutes les méthodes intégrées telles que l'épissure, la tranche, la poussée, le décalage, la pop, l'alternance, la tri, l'inversion et bien d'autres … Donc, ce serait Terrible pratique de codage. Mais cela ne fonctionne pas comme Ray l'a souligné parce qu'il est en lecture seule.

Cette petite pièce de code démontrera que Array.prototype ne peut pas être remplacé car la méthode de sort sera toujours exécutée:

 <script type="text/javascript"> Array.prototype={}; var a=new Array(1,4,5,7,8); a.sort(); alert(a.join(",")); </script> 

Si vous souhaitez remplacer les propriétés prototypes pour Array.prototype, vous devez le faire une à la fois comme Array.prototype.aa='aa'; : Array.prototype.aa='aa';

Si vous souhaitez appliquer une grande quantité de propriétés à Array.prototype, appliquez-le par une boucle. Voici un code que j'ai écrit pour vous qui devrait accomplir exactement ce que vous essayez de faire:

 <script type="text/javascript"> function my() { this.aa = 'aa'; } my.prototype.bb = "bb"; var instance = new my(); for(var j in instance) { if(instance.hasOwnProperty(j) || j in my.prototype) { Array.prototype[j]=instance[j]; } } var book=new Array(); book[0]="War and Peace"; alert(book.aa);//alerts "aa" alert(book.bb);//alerts "bb" </script>