带参数的Javascript构造函数

时间:2012-09-30 11:40:30

标签: javascript inheritance constructor prototypal-inheritance

在尝试理解javascript构造函数时,我一直在关注this question

在我看来,我理解它是合理的,但具有讽刺意味的是,当我尝试运行类似的代码时,它根本不适用于我。

这是我的代码

function Car(name) {
    this.Name = name;
    this.Year = 1999;
}

Car.prototype.Drive = function() {
    document.write("My name is '" + this.Name + "' and my year is '" + this.Year + "'. <br />");
};

SuperCar = function () { };
SuperCar.prototype = new Car();

function SuperCar(name) {
    Car.call(this, name);
}

var MyCar = new Car("mycar");
var MySuperCar = new SuperCar("my super car");

MyCar.Drive();
MySuperCar.Drive();

首先,这一行

SuperCar = function () { };

对于它来说是必要的。如果我把它留下来,我就会在这一行错误“SuperCar is undefined”。

SuperCar.prototype = new Car();

我真的不明白为什么将SuperCar声明为空函数是必要的。

其次,当我运行代码时,我得到了这个结果

My name is 'mycar' and my year is '1999'. 
My name is 'undefined' and my year is '1999'. 

显然,对于MySuperCar,从不调用SuperCar(名称)函数,但Car()是。

添加此行没有帮助

SuperCar.prototype.constructor = SuperCar;

这也不是

SuperCar.prototype.constructor = function(name) {
    Car.call(this, name);
};

(我一直在IE 9和Chrome 22上的脚本标签内运行代码)

如何使用name参数正确定义SuperCar构造函数?换句话说,如何让新的SuperCar(“我的超级跑车”)通话按照我的预期行事(将名称设置为“我的超级跑车”)?

2 个答案:

答案 0 :(得分:4)

您不应该真正创建Car的实例作为原型,而只创建一个继承自Car.prototype的对象。有关详细信息,请参阅What is the reason to use the 'new' keyword at Derived.prototype = new Base。相反,使用

SuperCar.prototype = Object.create(Car.prototype);

你的问题是你的SuperCar是由空函数创建的 - 它返回一个没有任何属性的对象。然而,他们继承自new Car()nameundefined。这发生在你的小提琴中,因为函数声明(以function关键字开头,结帐this explanation)被提升(在范围内的任何地方都可用)并被行覆盖< / p>

SuperCar = function () { };

这样您的SuperCar构造函数就不再调用Car构造函数了。 Fixed fiddle

答案 1 :(得分:2)

你不需要空函数。你创建了一个空的SuperCar函数,然后设置了它的原型,然后使用 new 定义SuperCar覆盖了它。

function SuperCar() {}
SuperCar.prototype = new Car();

function SuperCar() {} // original SuperCar overwritten