当前位置: 代码迷 >> JavaScript >> 原型继承导致共享引用
  详细解决方案

原型继承导致共享引用

热度:8   发布时间:2023-06-07 11:45:32.0

我想了解原型在Java脚本中的作用以及为什么。 在以为自己知道发生了什么之后,我迷上了一个事实,那就是原型只是一个对象,不能像我所想的那样被许多对象“共享”。 让我举例说明:

var SpritePrototype = {
    img: null,
    pos_x: 0,
    pos_y: 0,

    draw: function(context2d) {
        /*do stuff with the canvas
          using "this" to refer to 
          the object this method is 
          being called on*/
    },
    //Some more member functions...
}

从通常使用原型友好的Javascript提倡的“对象继承自对象”的概念出发,我认为我可以做到:

var player = Object.create(SpritePrototype);

但是事实证明这种方法是有缺陷的,因为非功能性字段将是SpritePrototype的字段,因为玩家的原型正是SpritePrototype。 这意味着我无法从该原型创建更多的对象,否则非功能性字段将被混合使用。

那么,Object.create的意义何在?更重要的是,实现我想要做的事情的正确方法是什么? 也就是说,如何使“玩家”获得字段的副本并从其原型继承功能?

同样,我对按预期方式进行操作感兴趣。 我总是可以手动模拟继承,也可以完全跳过继承。 我的问题的重点是了解原型以及原型的使用方式和时间,特别是在我的特定情况下。

原型上的属性值最初是共享的,但是在实例上的属性值被写入(分配)后停止共享。 那时,实例将获得其自己的属性版本。 因此,说该值是“共享的”并不完全正确。 仅在实例属性分配到的时间点之前共享。

var SpritePrototype = {
    img: 'img1'
};
var sprite1 = Object.create(SpritePrototype);
var sprite2 = Object.create(SpritePrototype);

sprite1.img = 'img2';            // does NOT affect prototype or sprite2
console.log(sprite2.img);

< "img1"

引用img ,其值取自原型。 但是,在写入 img时,将在实例上创建一个新属性来保存新值,并从此开始使用。

更改原型上的属性值的唯一方法是显式更改:

SpritePrototype.img = 'img3';

这将通过分配所有尚未定义其本地img版本的实例来更改img

您的问题是,已根据面向对象的设计定义了“静态”成员。 原型部分中的所有内容在对象之间共享。 函数实际上并不会复制到新创建的对象,但是会使用适当的“ this”进行调用。

您应该在构造函数中初始化变量,如下所示

function Sprite(...) {
    this.img = null;
    ...
}

然后对于子类型,您应该使用Object.create创建一个原型来继承其方法,因此

Player.prototype = Object.create(Sprite.prototype);

最后,您可以调用父构造函数来初始化变量

function Player(...) {
    Sprite.call(this, ...);
}

PS。 构造函数应在Player.prototype分配之前。

PPS。 有关更多信息,请参见

  相关解决方案