// Base class
var Base = function() {
this._value = 'base';
};
Base.prototype = {
constructor: Base,
// By function
getValue: function() {
return this._value;
},
// By getter
get value() {
return this._value;
}
};
// Sub class extends Base
var Sub = function() {
this._value = 'sub';
};
Sub.prototype = {
constructor: Sub
};
// Pass over methods
Sub.prototype.getValue = Base.prototype.getValue;
Sub.prototype.value = Base.prototype.value;
// ---
var mySub = new Sub();
alert(mySub.getValue()); // Returns 'sub'
alert(mySub.value); // Returns 'undefined'
乍一看似乎mySub.value应该与mySub.getValue()返回相同,但正如你所看到的那样,它返回undefined。显然,getter没有找到父作用域作为Sub实例(mySub),而是找不到基本实例。
除了必须将相同的吸气剂分配到新原型之外,还有其他方法吗?
答案 0 :(得分:11)
Sub.prototype.__defineGetter__('value', Base.prototype.__lookupGetter__('value'));
试试。
答案 1 :(得分:6)
更现代的解决方案是使用Object.defineProperty
,因为它允许处理getter和setter而不会破坏它们。
唯一的问题是它需要一个描述符对象,而不是手动使用Object.getOwnPropertyDescriptor
函数来为你获取它。
var BazValue = Object.getOwnPropertyDescriptor(Base.prototype,'value');
Object.defineProperty(Sub.prototype,'value',BazValue);
答案 2 :(得分:5)
我认为如果你分配
会有用Sub.prototype = new Base()
问题是,当您从Base.prototype.value直接分配构造函数时,它永远不会运行。在拥有Base类的实例(通过new
)
这是我扩展Function
以实现继承的典型方法:
Function.prototype.Extend = function(superClass) {
this.prototype = new superClass();
this.prototype.getSuperClass = function() {
return superClass;
};
this.getSuperClass = this.prototype.getSuperClass;
return this;
};
这将正确地将所有父类方法和属性分配给子“类”。
用法类似于
var Sub = function() {}
Sub.Extend(Base)
答案 3 :(得分:2)
除了Alex Mcp的答案之外,您可以在使用以下内容扩展它之后向Sub添加新的getter / setter:
Function.prototype.addGetter = function(val,fn){
this.prototype.__defineGetter__(val,fn);
return this;
}
Function.prototype.addSetter = function(val,fn){
this.prototype.__defineSetter__(val,fn);
return this;
}
//example;
Sub.Extend(Base);
Sub.addGetter('date',function(){return +new Date;});
要添加到tylermwashburns回答:您可以扩展函数原型:
Function.prototype.copyGetterFrom = function(val,fromConstructor){
this.prototype.__defineGetter__(
val
,fromConstructor.prototype.__lookupGetter__(val));
return this;
}
//usage example.:
Sub.copyGetterFrom('value',Base);