Object members that are prototyped as arrays become shared by all class instances

Has anyone noticed this behavior before? This really threw me off… I would have expected prototyped arrays to be private to each class instance rather than shared between all class instances.


<html>
<head>

<script type="text/javascript">

function print_r( title, object ) {

	var output = '';
	for( var key in object ) {

		output += key + ": " + object[ key ] + "\
";

	}

	output = title + "\
\
" + 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>

If the Sandwich object doesn’t have the array, then it look further up the scope to its prototype for the array instead.

Since the prototype is referenced by all objects extended from it, all functions and parameters are referenced, not copied. The behavior may be unexpected if that’s not known, but it makes sense.

You did the right thing there by placing the ingredients array within the Sandwich object itself, so that the information remains local to each individual object.

Thanks, I did not realize that was the expected behavior. For some reason I thought arrays were special and were copied from the prototype rather than referenced.

It can take several re-reads to take in, but the following seems to cover this ground really well.

http://www.jibbering.com/faq/notes/closures/