我想了解原型在Javascript中的用途和原因。在我以为我知道发生了什么之后,我偶然发现原型只是一个物体而且不能像我想象的那样被许多物体“共享”。让我详细说明一下:
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中的重点是什么,更重要的是,实现我想要做的事情的正确方法是什么?也就是说,如何让“播放器”获取字段的副本并从其原型继承功能?
同样,我有兴趣以他们想要的方式做事。我总是可以手工模拟继承或完全跳过它。我的问题是要了解原型以及它们如何以及何时有用,特别是在我的特定情况下。
答案 0 :(得分:3)
原型上的属性值最初是共享的,但在写入(分配)实例上的该属性时停止共享。在那一刻,实例获得了自己的属性版本。所以说价值是“共享”并不完全正确。它仅在实例的属性分配到的时间点共享。
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
。
答案 1 :(得分:1)
你的问题是,你已经定义了&#34;静态&#34;面向对象设计的成员。 protoype部分中的所有内容都在对象之间共享。函数实际上没有被复制到新创建的对象,但它被正确调用&#34;这个&#34;。
您应该在构造函数中初始化变量,例如
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