简体   繁体   English

继承:构造函数不运行“超级”?

[英]Inheritance: Constructor doesn't run “super”?

I've run into this behavior after using JS for a few months. 使用JS几个月后我遇到了这种行为。 I'm very puzzled because of my Java background: I create a class and make subclasses. 由于我的Java背景,我很困惑:我创建了一个类并创建了子类。 Call a subclass' constructor won't call the parent constructor. 调用子类的构造函数不会调用父构造函数。 Ok, I read about this behavior, it seems normal, right? 好的,我读到了这个行为,看起来很正常,对吧?

See this jsfiddle example to help me clarify. 请参阅此jsfiddle 示例以帮助我澄清。

So to have my subclass constructor run each of its parent constructor, I'm adding the following (see jsfiddle example 因此,要让我的子类构造函数运行其每个父构造函数,我将添加以下内容(请参阅jsfiddle 示例

Ok, seems to work better this way. 好吧,这种方式看起来效果更好。 Now, I'm wondering about the following; 现在,我想知道以下几点; Is there a way to specify wich is the superclass without trigger its constructor? 有没有办法指定哪个是超类而不触发它的构造函数? Like for instance the following runs the Node() method: 例如,以下运行Node()方法:

GameObject.prototype = new Node();
GameObject.prototype.constructor=GameObject;

(see updated jsfiddle example ) (参见更新的jsfiddle 示例

I can't help but feel I'm not doing it right. 我情不自禁地觉得我做得不对。 As my real model is layered across 7 subclasses, there's a total of 21 calls to my constructors (6 + 5 + 4 + 3 + 2 + 1 = 21). 由于我的真实模型分为7个子类,因此对我的构造函数总共有21个调用(6 + 5 + 4 + 3 + 2 + 1 = 21)。

Am I doing something wrong? 难道我做错了什么? Thanks for your time! 谢谢你的时间!

You're not doing anything wrong, per-se. 你本来没有做错任何事。 This is the expected behavior given your code. 这是给出代码的预期行为。 You can, however, use an approach similar to the one described in "Simple JavaScript Inheritence" by John Resig . 但是,您可以使用类似于John Resig的“Simple JavaScript Inheritence”中描述的方法。 Another discussion of a similar approach can be found here on stackoverflow . 可以在stackoverflow上找到类似方法的另一个讨论。

You don't need to call the parent's constructor just to setup the inheritance chain. 您不需要仅调用父的构造函数来设置继承链。 See http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html 请参阅http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

The following is bad, runs the parent's constructor just to setup the prototype chain 以下是不好的,运行父的构造函数只是为了设置原型链

GameObject.prototype = new Node();
GameObject.prototype.constructor = GameObject;

The better way is to use a surrogate constructor that attaches the prototype without instantiating the "super class". 更好的方法是使用代理构造函数来附加原型而不实例化“超类”。

// Surrogate constructor
var TempCtor = function(){};
TempCtor.prototype = Node.prototype;
// Setup the prototype chain without side effects
GameObject.prototype = new tempCtor();
GameObject.prototype.constructor=GameObject;

And you need to make sure you call the parent constructor from the subclass 并且您需要确保从子类调用父构造函数

function GameObject() {
    // Call the parent's constructor
    Node.call(this);
}

I've updated your jsfiddle with an example that shows the correct way to setup inheritance http://jsfiddle.net/2caTD/5/ 我已经用一个示例更新了你的jsfiddle,它显示了设置继承的正确方法http://jsfiddle.net/2caTD/5/

My understanding is that JavaScript doesn't naively implement classes the way traditional languages like C++, Java, and C# do. 我的理解是JavaScript并不像C ++,Java和C#这样的传统语言那样天真地实现类。 I think you can get the behaviour you want by using a JavaScript framework that imposes the behaviors you are used to in langauges like Java. 我认为你可以通过使用一个JavaScript框架来获得你想要的行为,这个框架强加了你习惯的行为,比如Java。

Moo Tools is one such framework: http://mootools.net Moo Tools就是这样一个框架: http//mootools.net

Generally, you're doing it right. 一般来说,你做得对。 But your constructor function creates properties on its instances and those properties get assigned to the inheriting constructor's prototype. 但是构造函数会在其实例上创建属性,并将这些属性分配给继承构造函数的原型。

Subclass.prototype.animations , for example are on the prototype, shared by all further instances of Subclass . Subclass.prototype.animations ,例如是在原型,通过所有进一步的实例共享Subclass From your code it seems like you intended these animations to be created anew for each instance. 从您的代码中,您似乎希望为每个实例重新创建这些animations

How to resolve this problem? 如何解决这个问题? Don't use constructor functions at all. 根本不要使用构造函数。 Use object literals and Object.create . 使用对象文字和Object.create

var Node = {
    init: function () { this.animations = []; },
    doSomething: function () { console.log(this.animations); }
};

var GameObject = Object.create(Node);
GameObject.doSomethingElse = function () { this.init(); this.doSomething(); }

Instantiate the same way you inherit: 以与继承相同的方式实例化:

var gameObj = Object.create(GameObject);
gameObj.doSomethingElse();

It shouldn't be more difficult than that. 它不应该比那更困难。

See Combining inheritance with the module pattern . 请参阅将继承与模块模式组合在一起

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM