我想使用Javascript做一些继承。问题是我不知道如何在继承的对象上保留A类原型。
这是我的代码:
function Base() {
this.attribute1 = null;
}
Base.prototype = {
baseFunction: function() {}
};
function SubBase()
{
Base.call(this); // Constructor call
this.baseFunction();
this.subBaseFunction();
}
SubBase.prototype = Base.prototype;
SubBase.prototype = {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
}
通过这种方式,我删除Base.prototype
,但我不想。
我尝试了SubBase.prototype.__proto__ = Base.prototype;
但it is apparently too slow。
我知道我可以做(但是写的时间太长而且对我来说不干净):
SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};
我该怎么做/写得更好?
答案 0 :(得分:5)
而不是:
SubBase.prototype = Base.prototype;
SubBase.prototype = {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
}
你需要将每个额外的方法添加到现有的原型对象上,以避免覆盖刚刚放在那里的Base.prototype
:
// establish the prototype we're inheriting from
// make a new object into the prototype so when we change it, it
// doesn't change the original
SubBase.prototype = Object.create(Base.prototype);
// now add more methods onto the inherited prototype
SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};
注意:您也不想只分配Base.prototype
,因为当您更改SubBase.prototype
时,您实际上会更改两个对象(对象分配只是一个参考)。所以在这里,我使用Object.create(Base.prototype)
创建该原型的副本。
许多库支持某种extend()
函数,它将属性从一个对象复制到另一个对象。这允许您定义一个单独的方法对象,然后"添加"它是现有的原型,但是这个功能并不是内置于普通的javascript。
例如在jQuery中,你可以这样做:
// establish the prototype we're inheriting from
SubBase.prototype = Object.create(Base.prototype);
jQuery.extend(SubBase.prototype, {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
});
或者,<2016年更新 ,ES6包含Object.assign()
function,它会将属性从一个对象复制到另一个对象:
Object.assign(SubBase.prototype, {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
});
或者,您可以创建自己的函数,只需几行代码就可以将属性从一个对象复制到另一个对象。
或者,普通javascript中的相同代码:
// copy properties from src to target
function copyProperties(target, src) {
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
target[prop] = src[prop];
}
}
return(target);
}
// establish the prototype we're inheriting from
SubBase.prototype = Object.create(Base.prototype);
copyProperties(SubBase.prototype, {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
});
这是我通常使用的风格:
function Base() {
this.attribute1 = null;
}
Base.prototype = {
baseFunction: function() {}
};
function SubBase()
{
Base.apply(this, arguments); // Constructor call with arguments
}
(function() {
var proto = SubBase.prototype = Object.create(Base.prototype);
proto.constructor = SubBase;
proto.subBaseFunction = function() {
// code here
};
proto.subBaseOtherFunction = function() {
// code here
};
})();
答案 1 :(得分:3)
首先,你实际上并没有从Base继承......你只是在向它添加函数。
SubBase.prototype = Base.prototype;
SubBase.prototype.foo = true;
alert(Base.prototype.foo);
要设置继承链,您需要将base的实例指定为原型:
SubBase.prototype = new Base();
然后你增加它,就像你在帖子中一样:
SubBase.prototype.newFunction = function () { };
以这种方式进行继承的一个缺点是你的基类构造函数不能接收参数。如果需要,那么您需要使用Object.create
来设置继承,并手动调用基类构造函数:
function Base(x) {
alert(x);
};
Base.prototype.baseFunction = function () {
alert('called method from base class');
};
function SubBase(x) {
Base.call(this, x);
};
SubBase.prototype = Object.create(Base.prototype);
var instance = new SubBase(1);
instance.baseFunction();
答案 2 :(得分:0)
您可以使用jQuery.extend():
SubBase.prototype = {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
};
$.extend(SubBase.prototype, Base.prototype);
请参阅:http://jsfiddle.net/dd6UC/
jQuery.extend()docs:http://api.jquery.com/jquery.extend/