以数组为原型的 Javascript 对象成员由所有类实例共享

2023-12-29

以前有人注意到这种行为吗?这真的让我很失望......我本来期望原型数组对于每个类实例都是私有的,而不是在所有类实例之间共享。

有人可以验证这是正确的行为,并且也许可以更详细地解释这种行为吗?

请注意注释的代码以及它如何影响脚本的行为。

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

非常感谢。


对象的原型只是一个对象。原型属性在所有对象之间共享inherit来自那个物体。如果您创建“类”的新实例(JS 中不存在类),即从原型继承的对象,则不会创建属性的副本。

它仅对您如何使用这些继承的属性产生影响:

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

在所有这些情况下,您始终使用同一个对象。

但如果你assign对象属性的值,该属性将在对象本身而不是其原型上设置/创建,因此不会共享:

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

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

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

因为在这里,this指的是new调用时生成的对象new Foo().

经验法则是:Instance-具体数据应分配给instance在 - 的里面构造函数, shared数据(如方法)应分配给原型.


您可能想阅读对象模型的详细信息 https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model它描述了基于类的语言与基于原型的语言之间的差异以及对象的实际工作方式。

Update:

您可以通过以下方式访问对象的原型Object.getPrototypeOf(obj)(可能无法在非常旧的浏览器中工作),并且Object.getPrototypeOf(a) === Object.getPrototypeOf(b)给你true。它是同一个对象,也称为Foo.prototype.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以数组为原型的 Javascript 对象成员由所有类实例共享 的相关文章

随机推荐