tho*_*ron 1 javascript oop inheritance prototype
我想用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() {}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式我擦除Base.prototype但我不想.
我试过SubBase.prototype.__proto__ = Base.prototype;但显然太慢了.
我知道我可以做(但是写的时间太长而对我来说不是那么干净):
SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};
Run Code Online (Sandbox Code Playgroud)
我该怎么做/写得更好?
而不是这个:
SubBase.prototype = Base.prototype;
SubBase.prototype = {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
}
Run Code Online (Sandbox Code Playgroud)
你需要将每个额外的方法添加到现有的原型对象上,以避免覆盖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() {};
Run Code Online (Sandbox Code Playgroud)
注意:您也不想只是分配,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() {}
});
Run Code Online (Sandbox Code Playgroud)
或者,在2016年更新,ES6包含一个将属性从一个对象复制到另一个对象的Object.assign()函数:
Object.assign(SubBase.prototype, {
subBaseFunction: function() {},
subBaseOtherFunction: function() {}
});
Run Code Online (Sandbox Code Playgroud)
或者,您可以创建自己的函数,只需几行代码就可以将属性从一个对象复制到另一个对象.
或者,普通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() {}
});
Run Code Online (Sandbox Code Playgroud)
这是我通常使用的风格:
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
};
})();
Run Code Online (Sandbox Code Playgroud)
首先,您实际上并不是从 Base 继承......您只是向其添加函数。
SubBase.prototype = Base.prototype;
SubBase.prototype.foo = true;
alert(Base.prototype.foo);
Run Code Online (Sandbox Code Playgroud)
要设置继承链,您需要指定一个 base 实例作为原型:
SubBase.prototype = new Base();
Run Code Online (Sandbox Code Playgroud)
然后你对其进行扩充,就像你在帖子中所做的那样:
SubBase.prototype.newFunction = function () { };
Run Code Online (Sandbox Code Playgroud)
以这种方式进行继承的一个弱点是基类构造函数无法接收参数。如果您需要它,那么您需要使用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();
Run Code Online (Sandbox Code Playgroud)