12
// 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) として親スコープを見つけているのではなく、存在しない Base インスタンスを見つけています。

同じゲッターを新しいプロトタイプに割り当てる以外に、これを回避する方法はありますか?

4

4 に答える 4

12

より現代的な解決策は、Object.definePropertygetter と setter を壊さずに処理できるようにするため、 を使用することです。

唯一の問題は、記述子オブジェクトを使用することです。そのため、手動で作成する代わりに、Object.getOwnPropertyDescriptor関数を使用してそれを取得してください。

var BazValue = Object.getOwnPropertyDescriptor(Base.prototype,'value');

Object.defineProperty(Sub.prototype, 'value', BazValue);
于 2016-01-05T18:45:25.913 に答える
11
Sub.prototype.__defineGetter__('value', Base.prototype.__lookupGetter__('value'));

それを試してみてください。

于 2011-05-18T04:00:09.803 に答える
6

割り当てればうまくいくと思います

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)
于 2011-05-18T03:56:05.393 に答える
2

Alex Mcpの回答に加えて、次を使用して拡張した後、新しいゲッター/セッターを Sub に追加できます。

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 プロトタイプを拡張できます。

Function.prototype.copyGetterFrom = function(val,fromConstructor){
    this.prototype.__defineGetter__(
         val
        ,fromConstructor.prototype.__lookupGetter__(val));
    return this;   
}
//usage example.:
Sub.copyGetterFrom('value',Base);
于 2011-05-18T04:43:29.673 に答える