Los miembros de objects Javascript que son prototipados como matrices se comparten entre todas las instancias de classs

¿Alguien ha notado este comportamiento antes? Esto realmente me sorprendió … Hubiera esperado que los arrays de prototypes fueran privados para cada instancia de class en lugar de compartirse entre todas las instancias de class.

¿Puede alguien verificar que este es el comportamiento correcto y quizás explicar este comportamiento con más detalle?

Observe el código comentado y cómo afecta el comportamiento del 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.ingnetworkingients = []; } Sandwich.prototype = { "ingnetworkingients" : [], "addIngnetworkingients" : function( ingArray ) { for( var key in ingArray ) { this.addIngnetworkingient( ingArray[ key ] ); } }, "addIngnetworkingient" : function( thing ) { this.ingnetworkingients.push( thing ); } } var cheeseburger = new Sandwich(); cheeseburger.addIngnetworkingients( [ "burger", "cheese" ] ); var blt = new Sandwich(); blt.addIngnetworkingients( [ "bacon", "lettuce", "tomato" ] ); var spicy_chicken_sandwich = new Sandwich(); spicy_chicken_sandwich.addIngnetworkingients( [ "spicy chicken pattie", "lettuce", "tomato", "honey dijon mayo", "love" ] ); var onLoad = function() { print_r( "Cheeseburger contains:", cheeseburger.ingnetworkingients ); }; </script> </head> <body onload="onLoad();"> </body> </html> 

Muchas gracias.

El prototipo de un object es solo un object. Las properties del prototipo se comparten entre todos los objects que henetworkingan de ese object. No se realizan copys de las properties si crea una nueva instancia de una "class" (las classs no existen de todos modos en JS), es decir, un object que henetworkinga del prototipo.

Solo hace una diferencia sobre cómo usar estas properties henetworkingadas:

 function Foo() {} Foo.prototype = { array: [], func: function() {} } a = new Foo(); b = new Foo(); a.array.push('bar'); console.log(b.array); // prints ["bar"] b.func.bar = 'baz'; console.log(a.func.bar); // prints baz 

En todos estos casos, siempre está trabajando con el mismo object.

Pero si asigna un valor a una propiedad del object, la propiedad se establecerá / creará en el object mismo, no en su prototipo, y por lo tanto no se comparte:

 console.log(a.hasOwnProperty('array')); // prints false console.log(a.array); // prints ["bar"] a.array = ['foo']; console.log(a.hasOwnProperty('array')); // prints true console.log(a.array); // prints ["foo"] console.log(b.array); // prints ["bar"] 

Si desea crear matrices propias para cada instancia, debe definirlas en el constructor:

 function Foo() { this.array = []; } 

porque aquí, this refiere al new object que se genera cuando llamas a un new Foo() .

La regla general es: los datos específicos de instancia se deben asignar a la instancia dentro del constructor , los datos compartidos (como los methods) se deben asignar al prototipo .


Es posible que desee leer Detalles del model de objects que describe las diferencias entre los lenguajes basados ​​en classs y prototypes y cómo funcionan realmente los objects.

Actualizar:

Puede acceder al prototipo de un object a través de Object.getPrototypeOf(obj) (puede que no funcione en browseres muy antiguos), y Object.getPrototypeOf(a) === Object.getPrototypeOf(b) le da true . Es el mismo object, también conocido como Foo.prototype .

El comportamiento es correcto. [] se traduce en una new Array() en time de ejecución, pero solo se crea una.

En otras palabras, Obj.prototype = {...} se ejecuta como cualquier otra asignación.

Cuando hace var exp1 = new C() , JavaScript establece exp1.[[Prototype]] = C.prototype . Cuando accede a las properties de la instancia, JavaScript comtesting primero si existen en ese object directamente, y si no, se ve en [[Prototype]] . Esto significa que todas las cosas que define en el prototipo se comparten de manera efectiva en todas las instancias, e incluso más adelante puede cambiar partes del prototipo y hacer que los cambios aparezcan en todas las instancias existentes.