Javascript object members that are prototyped as arrays become shared by all class instances
之前有人注意到这种行为吗? 这真的让我失望......我原本希望原型数组对每个类实例都是私有的,而不是在所有类实例之间共享。
有人可以验证这是正确的行为,并可能更详细地解释这种行为?
请注意注释的代码以及它如何影响脚本的行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <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 ); }; </head> <body onloadx="onLoad();"> </body> </html> |
非常感谢。
对象的原型只是一个对象。原型属性在从该对象继承的所有对象之间共享。如果您创建"类"的新实例(JS中不存在类),则不会创建属性的副本,即从原型继承的对象。
它只会对您使用这些继承属性的方式产生影响:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
在所有这些情况下,您始终使用相同的对象。
但是,如果为对象的属性赋值,则将在对象本身而不是其原型上设置/创建属性,因此不会共享:
1 2 3 4 5 6 | 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"] |
如果要为每个实例创建自己的数组,则必须在构造函数中定义它:
1 2 3 | function Foo() { this.array = []; } |
因为在这里,
经验法则是:应将特定于实例的数据分配给构造函数内的实例,应将共享数据(如方法)分配给原型。
您可能希望阅读对象模型的详细信息,该模型描述了基于类的语言与基于原型的语言之间的差异以及对象实际的工作方式。
更新:
您可以通过
行为是正确的。
换句话说,
当你执行