javascript - 原型(prototype)继承导致共享引用

标签 javascript inheritance prototype prototypal-inheritance

我想了解原型(prototype)在 Javascript 中如何以及为何有用。当我以为我知道发生了什么之后,我无意中发现原型(prototype)只是一个对象,不能按照我想象的方式被许多对象“共享”。让我用一个例子来详细说明:

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

根据原型(prototype)友好的 Javascript 通常提倡的“对象继承对象”的概念,我认为我可以这样做:

var player = Object.create(SpritePrototype);

但事实证明这种方法是有缺陷的,因为非函数字段将是来自 SpritePrototype 的字段,而玩家的原型(prototype)正是 SpritePrototype。这意味着我无法从该原型(prototype)创建更多对象,否则非函数字段将全部混合在一起。

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

再说一遍,我有兴趣按照预期的方式做事。我总是可以手动模拟继承或完全跳过它。我的问题的重点是了解原型(prototype)以及它们如何以及何时有用,特别是在我的具体情况下。

最佳答案

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

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时,其值取自原型(prototype)。但是,当写入img时,会在实例上创建一个新属性来保存新值,并从此开始使用。

更改原型(prototype)上的属性值的唯一方法是显式执行:

SpritePrototype.img = 'img3';

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

关于javascript - 原型(prototype)继承导致共享引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31891848/

相关文章:

javascript - 寻找解决方法,因为 radiobutton.click() 挂起 Safari 但在 Chrome 中有效

c++ - 从父方法调用子方法

c++ - 为什么不能将 const set<Derived*> 作为 const set<Base*> 传递给函数?

javascript - 如何在 node.js 中使用原型(prototype)

javascript - 在原型(prototype)中进行事件绑定(bind)是否明智,为什么它的上下文会丢失?

javascript - 在第一个请求失败后,如何设法发出不同的请求

javascript - 无法在phonegap中将文件上传到Amazon S3

JAVA:如何调用Object的子类中的方法?

javascript - 如何在Javascript对象中实现多个新功能?

javascript - spritesheet 和 css 类哪个更高效