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

时间:2012-01-01 21:19:26

标签: javascript inheritance constructor prototype chaining

在使用JS几个月后,我遇到了这种行为。由于我的Java背景,我很困惑:我创建了一个类并创建了子类。 调用子类的构造函数不会调用父构造函数。好的,我读到了这个行为,看起来很正常,对吧?

请参阅此jsfiddle example以帮助我澄清。

因此,要让我的子类构造函数运行其每个父构造函数,我将添加以下内容(请参阅jsfiddle example

好的,似乎这种方式效果更好。 现在,我想知道以下几点;有没有办法指定哪个是超类而不触发它的构造函数? 例如,以下运行Node()方法:

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

(请参阅更新的jsfiddle example

我情不自禁地觉得我做得不对。由于我的真实模型分为7个子类,因此对我的构造函数总共有21个调用(6 + 5 + 4 + 3 + 2 + 1 = 21)。

我做错了吗?谢谢你的时间!

4 个答案:

答案 0 :(得分:2)

你本来没有做错任何事。这是给出代码的预期行为。但是,您可以使用类似于"Simple JavaScript Inheritence" by John Resig中描述的方法。可以找到关于类似方法的另一种讨论here on stackoverflow

答案 1 :(得分:1)

我的理解是JavaScript并不像C ++,Java和C#这样的传统语言那样天真地实现类。我认为你可以通过使用一个JavaScript框架来获得你想要的行为,这个框架强加了你习惯的行为,比如Java。

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

答案 2 :(得分:1)

一般来说,你做得对。但是构造函数会在其实例上创建属性,并将这些属性分配给继承构造函数的原型。

例如

Subclass.prototype.animations在原型上,由Subclass的所有其他实例共享。从您的代码中,您似乎希望为每个实例重新创建这些animations

如何解决此问题?根本不要使用构造函数。使用对象文字和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(); }

以与您继承的相同的方式实例化

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

这不应该比那更难。

请参阅Combining inheritance with the module pattern

答案 3 :(得分:1)

您不需要仅仅为了设置继承链而调用父的构造函数。见http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

以下是不好的,运行父的构造函数只是为了设置原型链

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

更好的方法是使用代理构造函数来附加原型而不实例化“超类”。

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

您需要确保从子类

调用父构造函数
function GameObject() {
    // Call the parent's constructor
    Node.call(this);
}

我已经通过一个示例更新了您的jsfiddle,该示例显示了设置继承的正确方法http://jsfiddle.net/2caTD/5/