您好我是Javascript OO的新手,想要了解有关继承的更多信息。希望你能提供一些建议!
我看到这篇精彩帖子: How to "properly" create a custom object in JavaScript?
讲述了如何在我的其他网站中看到一个类的继承,例如:
function man(x) {
this.x = x;
this.y = 2;
}
man.prototype.name = "man";
man.prototype.two = function() {
this.y = "two";
}
function shawn() {
man.apply(this, arguments);
};
shawn.prototype = new man;
上面的帖子声称为了在继承时不要调用“man”的构造函数,可以使用这样的帮助器:
function subclassOf(base) {
_subclassOf.prototype= base.prototype;
return new _subclassOf();
}
function _subclassOf() {};
shawn.prototype = subclassOf(man);
虽然我理解其意图,但我不明白为什么我们不能打电话
shawn.prototype = man.prototype;
我认为它的工作方式完全相同。还是有什么我想念的?提前谢谢!
答案 0 :(得分:10)
嗯,在我的拙见中,例子比言辞更好。以下所有示例都使用了您的代码,并添加了一些内容。
第一个例子将证明使用shawn.prototype = new man;
你正在调用构造函数两次
function man(h, w) {
SendMessage("man is created with height " + h + " and weight " + w);
this.height = h;
this.weight = w;
}
man.prototype.name = "man";
man.prototype.double = function() {
this.height *= 2;
this.weigth *= 2;
}
function shawn() {
man.apply(this, arguments);
};
function SendMessage(msg) {
document.getElementById("Console").innerHTML += msg + "<br />";
}
window.onload = function() {
shawn.prototype = new man;
var p = new shawn(180, 90);
SendMessage("Shawn height: " + p.height);
}
<div id="Console"></div>
如你所见,构造函数被调用两次 - 一次没有参数,然后是你给它的实际参数。
第二个例子证明使用subclassOf
解决了“双重调用”问题。
function man(h, w) {
SendMessage("man is created with height " + h + " and weight " + w);
this.height = h;
this.weight = w;
}
man.prototype.name = "man";
man.prototype.double = function() {
this.height *= 2;
this.weigth *= 2;
}
function shawn() {
man.apply(this, arguments);
};
function subclassOf(base) {
_subclassOf.prototype= base.prototype;
return new _subclassOf();
}
function _subclassOf() {};
function SendMessage(msg) {
document.getElementById("Console").innerHTML += msg + "<br />";
}
window.onload = function() {
shawn.prototype = subclassOf(man);
var p = new shawn(180, 90);
SendMessage("Shawn height: " + p.height);
}
<div id="Console"></div>
第三个例子显示了你对shawn.prototype = man.prototype
的想法有什么问题,我会解释一下。 shawn
继承自man
,因此我添加了仅应影响shawn
的新方法,称为marriage
(这当然会让他获得一些权重;)) - 方法不会影响基类man
,因为它不是从shawn
继承的,继承只是一种方式。但是......正如你在例子中看到的那样,普通的man
也可以结婚 - 大问题。
function man(h, w) {
SendMessage("man is created with height " + h + " and weight " + w);
this.height = h;
this.weight = w;
}
man.prototype.name = "man";
man.prototype.double = function() {
this.height *= 2;
this.weight *= 2;
}
function shawn() {
man.apply(this, arguments);
};
function SendMessage(msg) {
document.getElementById("Console").innerHTML += msg + "<br />";
}
window.onload = function() {
shawn.prototype = man.prototype;
var p = new shawn(180, 90);
SendMessage("Shawn height: " + p.height);
p.double();
SendMessage("Shawn height: " + p.height);
shawn.prototype.marriage = function() {
SendMessage("Shawn is getting married, current weight: " + this.weight);
this.weight += 20;
};
p.marriage();
SendMessage("Shawn weight: " + p.weight);
var q = new man(170, 60);
q.marriage();
SendMessage("q weight: " + q.weight);
}
<div id="Console"></div>
最后,第四个示例显示使用subclassOf
一切正常,因为shawn
正确地继承man
,而marriage
未传递给基类。< / p>
function man(h, w) {
SendMessage("man is created with height " + h + " and weight " + w);
this.height = h;
this.weight = w;
}
man.prototype.name = "man";
man.prototype.double = function() {
this.height *= 2;
this.weight *= 2;
}
function shawn() {
man.apply(this, arguments);
};
function subclassOf(base) {
_subclassOf.prototype= base.prototype;
return new _subclassOf();
}
function _subclassOf() {};
function SendMessage(msg) {
document.getElementById("Console").innerHTML += msg + "<br />";
}
window.onload = function() {
shawn.prototype = subclassOf(man);
var p = new shawn(180, 90);
SendMessage("Shawn height: " + p.height);
p.double();
SendMessage("Shawn height: " + p.height);
shawn.prototype.marriage = function() {
SendMessage("Shawn is getting married, current weight: " + this.weight);
this.weight += 20;
};
p.marriage();
SendMessage("Shawn weight: " + p.weight);
var q = new man(170, 60);
if (q.marriage)
q.marriage();
else
SendMessage("marriage is undefined for man");
SendMessage("q weight: " + q.weight);
}
<div id="Console"></div>
希望这有一定道理! :)
答案 1 :(得分:5)
shawn.prototype = man.prototype;
将共享原型,即修改一个将修改另一个原型。
shawn.prototype = new man;
会将shawn.prototype
设置为从man.prototype
继承的新创建的对象,因此对其的更改不会传播到man
个实例。
但是,使用new
意味着将执行构造函数man()
,这会产生不良的副作用。
最好通过
手动克隆原型shawn.prototype = Object.create(man.prototype);
如果可用或custom clone function(其工作方式与subclassOf
相同)
shawn.prototype = clone(man.prototype);
否则。
答案 2 :(得分:1)
除了@ Shadow的优秀答案,您可以将shawn.prototype = man.prototype
视为"shawn is the same as man"
,而不是"shawn is a man"