Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么不';t我使用Child.prototype=Parent.prototype而不是Child.prototype=new Parent();对于Javascript继承?_Javascript_Inheritance - Fatal编程技术网

为什么不';t我使用Child.prototype=Parent.prototype而不是Child.prototype=new Parent();对于Javascript继承?

为什么不';t我使用Child.prototype=Parent.prototype而不是Child.prototype=new Parent();对于Javascript继承?,javascript,inheritance,Javascript,Inheritance,我不理解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

我不理解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;
当我在Spaceship构造函数中执行console.log(这个)时,我可以看到proto属性被设置为Spaceship而不是GameObject,如果我删除它们,它将被设置为GameObject

如果我使用:

 Spaceship.prototype = GameObject.prototype;
我没有更多的问题了。这会阻止我的原因是我有另一个带有add()方法的对象,它会用以下代码检查该对象是否与GameObject匹配:

 if(object instanceof GameObject)
我不明白这两行可能会发生什么变化,所以当它们出现时继承会被破坏,我不确定用第二种方式继承是否好。有人能告诉我这件事吗?:)

如果你这样做

Spaceship.prototype=GameObject.prototype

然后,它们都指向同一个对象,因此您可以将所有内容都放在
GameObject
中,如果您向
Spaceship.prototype
,它也将被添加到
GameObject.prototype
。任务完成后,您可以通过向Spaceship.prototype添加一些东西来轻松测试它

至于

Spaceship.prototype = new GameObject();
这将调用可能有不希望的副作用的构造函数,您更希望使用:

Spaceship.prototype = Object.create(GameObject.prototype);
此处使用的
对象。创建
功能归结为:

Object.create = function( proto ) {
    function f(){}
    f.prototype = proto;
    return new f;
};

不过,现代浏览器已经具备了这一功能。

人们从来没有正确地解释过为什么你会在这个.hitBox中出现奇怪的行为(我想这就是你想说的)

如果通过调用父类型的构造函数来创建原型来执行继承,则会执行该父类型的构造函数一次以创建父类型的实例,然后子类型的所有实例将共享该实例作为其原型

问题在于,如果该构造函数有任何行将可变对象分配给该
,那么这些对象将是该原型上的属性,对这些对象的任何修改都将反映在子类型的所有实例中:

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

这将确保每个新的
宇宙飞船的父构造函数逻辑分别运行,并执行必要的初始化任务。

请注意
instanceof
是不好的做法,如果您可以避免使用它,您可能应该这样做。@Bergi它不适合使用多态性,并且在向继承树中添加更多类时可能会导致问题。换句话说,
instanceof
通常不能很好地与开/闭原则相结合。@Jasper:这听起来像是类的问题。如果继承操作正确,没有理由不在适当的地方使用“instanceof”。@Bergi您使用什么替代?我想再添加一个继承是没有问题的(例如,一个将继承宇宙飞船的对象,并且仍然将我的
(游戏对象的对象实例)
计算为true,对吗?我的意思是在mozila课程中,他们以某个对象为例,并执行此
(someobject.prototype instanceof object)
而且它是有效的,因为所有对象都继承自
Object
@Bergi我知道这是一个旧线程(但您刚刚关闭了另一个问题,作为这个问题的副本)。为了澄清此注释部分中的混乱,似乎草率使用
instanceof
可能会违反打开/关闭原则(请参阅),但我要说的是,谨慎地使用它来检查特定基类的实例并不能做到这一点。
instanceof
的关注点在强类型语言中更为相关,它可能会破坏类型系统。非常感谢,这解决了我的问题,我现在更了解继承了!)@杰弗里胡克你注意到你没有在任何地方定义
.hitBox
<代码>this.hit=新对象();这个.hitBox.x=x
可能应该是
this.hitBox=new Object()
是的,我在发布评论后看到了它,我做了很多更改^^^您应该提到,在使用
Object.create()
时,通常需要从子构造函数调用父构造函数。
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