当前位置: 首页 > 面试题库 >

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

侯沈义
2023-03-14
问题内容

有没有人注意到这种行为?这真的让我失望了。我希望原型数组对每个类实例都是私有的,而不是在所有类实例之间共享。

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

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

<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中始终不存在类),即从原型继承的对象,则不会复制属性。

它仅对如何使用这些继承的属性有所不同:

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

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

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

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

经验法则是:应将 实例* 特定的数据分配给 构造函数内部的实例,将 共享数据(如方法)分配给 原型 。 __ *
__

您可能需要阅读对象模型的详细信息其中描述了基于类的语言与基于原型的语言之间的差异以及对象的实际工作方式。

更新:

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



 类似资料:
  • 问题内容: 如果你有一个具有原始类型(例如Byte,Integer,Char等)的Java对象数组。有没有一种巧妙的方法可以将其转换为原始类型的数组?特别是可以做到这一点,而不必创建新的数组并遍历内容。 因此,例如 将其转换为最简洁的方法是什么 不幸的是,在Hibernate和我们无法控制的某些第三方库之间进行接口连接时,这是我们经常要做的事情。看来这是一个很普通的操作,所以如果没有捷径,我会感到

  • 本文向大家介绍举例说明JavaScript中的实例对象与原型对象,包括了举例说明JavaScript中的实例对象与原型对象的使用技巧和注意事项,需要的朋友参考一下 首先声明:javascript中每个对象都有一个constructor属性和一个prototype属性。constructor指向对象的构造函数,prototype指向使用构造函数创建的对象实例的原型对象。 在这段代码中会报错,sayN

  • 我有[{key1:value1,key2:value2},{key3:value3,key4:value4},...].我想将其转换为{value1:value2,value3:value4}

  • 问题内容: 我对Python 3中的和类有些困惑。也许有人可以消除我的困惑或提供一些其他信息。 我目前的理解是,每个类(除外)都从称为的基类继承。但是每个类(包括)也是该类的一个实例,它是自身的实例,并且也从继承。 我的问题是: 是否有一个原因/设计决策,为什么是的实例并从中继承?对象的/ class是否也可以是对象本身? 类()如何成为其自身的实例? 哪一个是真正的基类或? 我一直认为这将是最“

  • 问题内容: 在Python 3,是的实例和也是一个实例! 每个类如何可能从另一个派生? 有实施细节吗? 我使用进行了检查,根据Python文档,它检查子类是否派生自基类: 问题答案: 这是Python中的一种极端情况: Python中的所有内容都是一个对象,因此,由于所有内容的基本类型都是(在Python中是某种东西)是的实例。 因为是所有内容的基本 类型 ,所以它也是 类型 ,它是的实例。 请注

  • 问题内容: 该函数的第一行在:类上获取错误。 我遵循Django文档教程,并且它们具有相同的代码并正在运行。 我尝试调用一个实例。 也是我该类的models.py代码是… 无济于事,我仍然有这个错误。 我已经读过有关pylint的文章并进行了运行… 这没有帮助,即使github自述文件说… 防止有关Django生成的属性(例如Model.objects或Views.request)的警告。 我在我