被作为原型阵列Javascript对象成员成为所有类实例共享 [英] Javascript object members that are prototyped as arrays become shared by all class instances

查看:97
本文介绍了被作为原型阵列Javascript对象成员成为所有类实例共享的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人注意到了这种行为?这真把我摔下......我本来期望原型阵列是私有的,而不是所有的类实例之间共享的每一个类的实例。

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.

有人可以确认这是正确的行为,也许更详细地解释这种现象?

Can someone verify that this is the correct behavior and perhaps explain this behavior in more detail?

注意评论code和它是如何影响脚本的行为。

Notice the commented code and how it affects the behavior of the 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>

非常感谢。

推荐答案

对象的原型就是一个对象。原型属性是继承的从该对象的所有对象之间共享。如果你创建一个阶级(类不JS反正存在),即一个对象从原型继承的新实例的属性没有副本的。

The prototype of an object is just an object. The prototype properties are shared between all objects that inherit from that object. No copies of the properties are made if you create a new instance of a "class" (classes don't exist anyway in JS), i.e. an object which inherits from the prototype.

这不仅使你如何使用这些的继承属性的不同:

It only makes a difference on how you use the these inherited properties:

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

在所有这些情况下,您总是与同一个对象的工作。

In all these cases you are always working with the same object.

但是,如果你的分配的对象的属性值,属性将被设置/对象本身上创建的,而不是它的原型,因而不共享:

But if you assign a value to a property of the object, the property will be set/created on the object itself, not its prototype, and hence is not shared:

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


如果你想为每个实例创建自己的数组,必须在构造函数中定义它:


If you want to create own arrays for each instance, you have to define it in the constructor:

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

因为在这里,这个指的是当你调用生成对象新的Foo()

because here, this refers to the new object that is generated when you call new Foo().

经验法则是:实例特异性数据应被分配到的实例的的的构造函数中共享数据(如方法),​​应分配到的原型

The rule of thumb is: Instance-specific data should be assigned to the instance inside the constructor, shared data (like methods) should be assigned to the prototype.

您可能需要阅读 对象模型<详细信息/ EM> 类为主描述之间的差异与基于原型的语言和实际如何对象。

You might want to read Details of the object model which describes differences between class-based vs. prototype-based languages and how objects actually work.

更新:

您可以通过 Object.getPrototypeOf访问对象的原型(OBJ)(可能无法正常工作在很老的浏览器),和对象。 getPrototypeOf(一)=== Object.getPrototypeOf(b)为您提供真正。它是同一个对象,也被称为 Foo.prototype

You can access the prototype of an object via Object.getPrototypeOf(obj) (might not work in very old browsers), and Object.getPrototypeOf(a) === Object.getPrototypeOf(b) gives you true. It is the same object, also known as Foo.prototype.

这篇关于被作为原型阵列Javascript对象成员成为所有类实例共享的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆