在继承的javascript中,我不理解这种行为,我一直看到它是这样定义的:
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg;
this.hit = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
}
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
function Spaceship(){
console.log("instantiate ship");
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
但就我而言,这几句话:
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
当我在我的飞船构造函数中执行console.log(this)时,我可以看到proto属性被设置为Spaceship而不是GameObject,如果我删除它们,它将被设置为GameObject。
如果我用:
Spaceship.prototype = GameObject.prototype;
我对此不再有意见了。这阻碍我的原因是,我有另一个带有add()方法的对象,它用以下代码检查GameObject的对象惰性:
if(object instanceof GameObject)
我不明白这两行可能会改变什么,这样当继承出现时,继承就会中断,而且我也不确定如何进行继承,第二种方式是好的。有人能告诉我这件事吗?
发布于 2012-06-18 09:59:21
如果你这样做了
Spaceship.prototype = GameObject.prototype;
然后,它们都引用相同的对象,所以您最好在GameObject
中包含所有内容,如果向Spaceship.prototype
添加一些内容,那么它也将添加到GameObject.prototype
中。您可以通过在赋值后向Spaceship.prototype
添加一些内容来轻松地测试它。For example, in your case you can see that GameObject.prototype.constructor
is actually Spaceship
。
至于
Spaceship.prototype = new GameObject();
这会调用可能产生意外副作用的构造函数,您最好使用:
Spaceship.prototype = Object.create(GameObject.prototype);
这里使用的Object.create
功能可以归结为:
Object.create = function( proto ) {
function f(){}
f.prototype = proto;
return new f;
};
不过,现代浏览器已经具备了这一功能。
发布于 2015-01-17 13:14:01
从来没有人恰当地解释过为什么你在this.hitBox
上会有奇怪的行为(我认为这就是你想说的)。
如果通过调用父构造函数创建原型来进行继承,则只执行该父构造函数一次以创建父类型的实例,然后该子类型的所有实例将共享该一个实例作为它们的原型。
这方面的问题是,如果构造函数有任何将可变对象分配给this
的行,那么这些对象将是该原型上的属性,对这些对象的任何修改都将反映在子类型的所有实例中:
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 12 (oh noes! what happened)
console.log(sps2.hitBox.x); // 12
(“调用构造函数以生成原型”方法还有其他类似的问题,但我将把它留在这里。)
@Esailija建议使用Object.create(baseObject)
是解决这个问题的第一步。它创建了一个原型为baseObject
的新对象,但没有构造函数中设置的内容(这是一件好事,但它需要考虑。继续读下去。)
正如我刚才所说,这将创建一个对象,其中父构造函数中的初始化逻辑从未运行过,但在大多数情况下,该逻辑与对象的功能相关。因此,还需要做一件事,即让子构造函数调用父构造函数:
function Spaceship(oImg, x, y) {
// call parent constructor on this object and pass in arguments.
// you could also use default values for the arguments when applicable
GameObject.call(this, oImg, x, y);
// remainder of Spaceship constructor...
}
这将确保父构造函数逻辑为每个新Spaceship
分别运行,并执行必要的初始化任务。
发布于 2015-05-23 07:53:37
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg || {width:null, height: null};
this.hitBox = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = this.img.width;
this.hitBox.height = this.img.height;
}
function Spaceship(){
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
Spaceship.prototype = new GameObject();
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 9
console.log(sps2.hitBox.x); // 12
https://stackoverflow.com/questions/11088365
复制