原型继承导致共享引用

Prototypal inheritance causes shared references

我想了解原型在 Javascript 中的作用和原因。在我以为我知道发生了什么之后,我偶然发现原型只是一个对象,不能像我想的那样被许多对象"shared"。让我举例说明:

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通常提倡的"objects inheriting from objects"概念,我认为我可以这样做:

var player = Object.create(SpritePrototype);

但事实证明这种方法是有缺陷的,因为非功能字段将是SpritePrototype中的那些,因为玩家的原型正是SpritePrototype。这意味着我无法从该原型创建更多对象,否则非函数字段将全部混淆。

那么 Object.create 的意义何在,更重要的是,实现我想要做的事情的正确方法是什么?也就是说,如何让 "player" 获取字段的副本并从其原型继承函数?

再次重申,我对按预期方式做事很感兴趣。我总是可以手动模拟继承或完全跳过它。我的问题的重点是了解原型以及它们如何以及何时有用,尤其是在我的具体情况下。

您的问题是,您根据面向对象设计定义了 "static" 成员。原型部分中的所有内容都在对象之间共享。函数实际上并没有被复制到新创建的对象,但它是用适当的 "this".

调用的

你应该像这样在构造函数中初始化你的变量

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

然后对于子类型你应该使用Object.create创建一个原型来继承它的方法,所以

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

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

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

PS。构造函数应该在 Player.prototype 赋值之前。

PPS。有关详细信息,请参阅此 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

属性 原型上的值最初是共享的,但当实例上的 属性 被写入(分配)到时停止共享。在那一刻,该实例获得了它自己的 属性 版本。所以说这个值是 "shared" 并不完全正确。它仅在实例上的 属性 分配给的时间点之前共享。

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 的实例。