2012-10-10 17 views
5

ho impostato il prototipo di Array come istanza di my, penso book.aa visualizzerà "aa", ma visualizza "undefined", perché? Grazie!Perché non riesco a sovrascrivere il prototipo di `Array` (` Array.prototype`)?

<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> 

risposta

7

Non si può assegnare a Array.prototype perché prototype è una proprietà di sola lettura di Array.

Quindi, quando si scrive

Array.prototype = new my(); 

non succede nulla. Per capire perché, provare

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

Il risultato è

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

A meno che non ci si trova in modalità rigorosa, l'assegnazione non riesce in silenzio.

Ecco perché - e vedere http://jsfiddle.net/5Ysub/ - se si esegue

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); 

Si ottiene

undefinedbb 

I bb funziona perché è stato assegnato al veraArray.prototype quando è stato creato e impostare la proprietà bb.

È una buona cosa che Array.prototype non possa essere colpito, IMHO. :)

0

Anche se si poteva esclusione Array.prototype direttamente in quel modo, si perderebbe l'accesso a tutti i metodi built-in come la giunzione, fetta, spinta, spostamento, pop, non innesto, ordinare, invertire e molti altri ... Quindi sarebbe una pratica di codice terribile. Ma non funziona come ha sottolineato Ray perché è di sola lettura.

Questo pezzo di codice molto piccolo dimostrerà che Array.prototype non può essere sostituito perché il metodo sort sarà ancora eseguire:

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

Se si desidera ignorare le proprietà prototipo per Array.prototype, è necessario farlo uno alla un momento così: Array.prototype.aa='aa';

Se si desidera applicare una grande quantità di proprietà a Array.prototype, quindi applicarlo attraverso un ciclo. Ecco un codice che ho scritto per te che dovrebbe realizzare esattamente quello che stai cercando di fare:

<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> 
Problemi correlati