132

オーバーライドされている場合、JavaScriptのプロトタイプメソッドからベースメソッドを呼び出すことは可能ですか?

MyClass = function(name){
    this.name = name;
    this.do = function() {
        //do somthing 
    }
};

MyClass.prototype.do = function() {  
    if (this.name === 'something') {
        //do something new
    } else {
        //CALL BASE METHOD
    }
};
4

14 に答える 14

24

それを行う1つの方法は、基本メソッドを保存してから、オーバーライドされたメソッドから呼び出すことです。

MyClass.prototype._do_base = MyClass.prototype.do;
MyClass.prototype.do = function(){  

    if (this.name === 'something'){

        //do something new

    }else{
        return this._do_base();
    }

};
于 2009-02-18T13:25:23.740 に答える
16

あなたの例は、あなたが考えているようには機能しません。この部分:

this.do = function(){ /*do something*/ };

の定義を上書きします

MyClass.prototype.do = function(){ /*do something else*/ };

新しく作成されたオブジェクトには既に「do」プロパティがあるため、プロトタイプ チェーンは検索されません。

Javascript の継承の古典的な形式は扱いにくく、把握するのが困難です。代わりに Douglas Crockford の単純な継承パターンを使用することをお勧めします。このような:

function my_class(name) {
    return {
        name: name,
        do: function () { /* do something */ }
    };
}

function my_child(name) {
    var me = my_class(name);
    var base_do = me.do;
    me.do = function () {
        if (this.name === 'something'){
            //do something new
        } else {
            base_do.call(me);
        }
    }
    return me;
}

var o = my_child("something");
o.do(); // does something new

var u = my_child("something else");
u.do(); // uses base function

私の意見では、JavaScript でオブジェクト、コンストラクター、および継承を処理するより明確な方法です。詳しくは Crockfords Javascript: The good partsを参照してください。

于 2009-02-18T13:26:32.253 に答える
5

このような関数を定義する場合 (OOP を使用)

function Person(){};
Person.prototype.say = function(message){
   console.log(message);
}

プロトタイプ関数を呼び出す方法は 2 つあります。1) インスタンスを作成し、オブジェクト関数を呼び出します。

var person = new Person();
person.say('hello!');

もう1つの方法は... 2)プロトタイプから直接関数を呼び出すことです:

Person.prototype.say('hello there!');
于 2014-08-13T22:01:53.880 に答える
5

このソリューションはObject.getPrototypeOf

TestA持っているスーパーですgetName

TestBオーバーライドする子ですが、バージョンだけでなくバージョンgetNamegetBothNames呼び出しますsupergetNamechild

function TestA() {
  this.count = 1;
}
TestA.prototype.constructor = TestA;
TestA.prototype.getName = function ta_gn() {
  this.count = 2;
  return ' TestA.prototype.getName is called  **';
};

function TestB() {
  this.idx = 30;
  this.count = 10;
}
TestB.prototype = new TestA();
TestB.prototype.constructor = TestB;
TestB.prototype.getName = function tb_gn() {
  return ' TestB.prototype.getName is called ** ';
};

TestB.prototype.getBothNames = function tb_gbn() {
  return Object.getPrototypeOf(TestB.prototype).getName.call(this) + this.getName() + ' this object is : ' + JSON.stringify(this);
};

var tb = new TestB();
console.log(tb.getBothNames());

于 2016-08-21T08:08:34.277 に答える
4

別の方法:

// shape 
var shape = function(type){
    this.type = type;
}   
shape.prototype.display = function(){
    console.log(this.type);
}
// circle
var circle = new shape('circle');
// override
circle.display = function(a,b){ 
    // call implementation of the super class
    this.__proto__.display.apply(this,arguments);
}
于 2015-11-13T16:57:54.043 に答える
2

私の理解が正しければ、基本機能を常に実行し、その一部を実装に任せる必要があります。

「テンプレート方式」の設計パターンに助けられるかもしれません。

Base = function() {}
Base.prototype.do = function() { 
    // .. prologue code
    this.impldo(); 
    // epilogue code 
}
// note: no impldo implementation for Base!

derived = new Base();
derived.impldo = function() { /* do derived things here safely */ }
于 2009-02-18T13:11:00.950 に答える
1

スーパークラスの名前がわかっている場合は、次のようにすることができます。

function Base() {
}

Base.prototype.foo = function() {
  console.log('called foo in Base');
}

function Sub() {
}

Sub.prototype = new Base();

Sub.prototype.foo = function() {
  console.log('called foo in Sub');
  Base.prototype.foo.call(this);
}

var base = new Base();
base.foo();

var sub = new Sub();
sub.foo();

これは印刷されます

called foo in Base
called foo in Sub
called foo in Base

予想通り。

于 2015-02-25T22:56:17.110 に答える
0

さらに、その 1 つの特別なインスタンスだけでなく、すべてのインスタンスをオーバーライドする場合は、これが役立つ場合があります。

function MyClass() {}

MyClass.prototype.myMethod = function() {
  alert( "doing original");
};
MyClass.prototype.myMethod_original = MyClass.prototype.myMethod;
MyClass.prototype.myMethod = function() {
  MyClass.prototype.myMethod_original.call( this );
  alert( "doing override");
};

myObj = new MyClass();
myObj.myMethod();

結果:

doing original
doing override
于 2015-03-26T10:47:51.450 に答える
0

いいえ、コンストラクターの do 関数とプロトタイプの do 関数に異なる名前を付ける必要があります。

于 2009-02-18T13:28:59.643 に答える
-1
function MyClass() {}

MyClass.prototype.myMethod = function() {
  alert( "doing original");
};
MyClass.prototype.myMethod_original = MyClass.prototype.myMethod;
MyClass.prototype.myMethod = function() {
  MyClass.prototype.myMethod_original.call( this );
  alert( "doing override");
};

myObj = new MyClass();
myObj.myMethod();
于 2015-05-25T04:45:56.993 に答える