Qualcuno ha notato questo comportamento prima? Questo mi ha davvero sconvolto ... mi sarei aspettato che gli array prototipati fossero privati per ogni istanza di classe piuttosto che condivisi tra tutte le istanze di classe.I membri di oggetti Javascript che vengono prototipati come matrici vengono condivisi da tutte le istanze di classe
Qualcuno può verificare che questo sia il comportamento corretto e forse spiegare questo comportamento in modo più dettagliato?
Si noti il codice commentato e il modo in cui influisce sul comportamento dello script.
<html>
<head>
<script type="text/javascript">
function print_r(title, object) {
var output = '';
for(var key in object) {
output += key + ": " + object[ key ] + "\n";
}
output = title + "\n\n" + output;
alert(output);
}
function Sandwich() {
// Uncomment this to fix the problem
//this.ingredients = [];
}
Sandwich.prototype = {
"ingredients" : [],
"addIngredients" : function(ingArray) {
for(var key in ingArray) {
this.addIngredient(ingArray[ key ]);
}
},
"addIngredient" : function(thing) {
this.ingredients.push(thing);
}
}
var cheeseburger = new Sandwich();
cheeseburger.addIngredients([ "burger", "cheese" ]);
var blt = new Sandwich();
blt.addIngredients([ "bacon", "lettuce", "tomato" ]);
var spicy_chicken_sandwich = new Sandwich();
spicy_chicken_sandwich.addIngredients([ "spicy chicken pattie", "lettuce", "tomato", "honey dijon mayo", "love" ]);
var onLoad = function() {
print_r("Cheeseburger contains:", cheeseburger.ingredients);
};
</script>
</head>
<body onload="onLoad();">
</body>
</html>
Molte grazie.
Hmm ... Sì, questo ha senso. Ho fatto l'errore di aspettarmi che il prototipo funzionasse come farebbe una definizione di classe. La cosa confusa è che se Foo.prototype.intValue = 5, e dici b.intValue = 4, a.intValue still = 5. Quindi si applica solo ai membri dell'oggetto/array della classe. – Dan
Poi di nuovo, se dici b.array = ['whatever'], allora a.array non cambia neanche. Pertanto, le assegnazioni esplicite che utilizzano l'operatore "=" sovrascrivono le proprietà prototipate su un oggetto istanziato. – Dan
@Dan: No, ho anche mostrato nel mio codice che 'a.array = ['foo'];' non cambierà il prototipo. Ma nel tuo caso con il numero intero e nel mio caso con l'array, stai assegnando un valore totalmente nuovo a una proprietà. E se lo fai, la proprietà sarà impostata sull'oggetto reale. Ma se si esegue 'a.array.push (1)', si ** non ** si imposta una proprietà, si sta semplicemente chiamando un metodo nella matrice contenuta in 'a.array'. Non stai cambiando il riferimento. –