0

c以下のオブジェクトがオブジェクト インスタンスの損失を回避するために使用する手法はb、私には少し匂いがします。もっと受け入れられる方法はありますか?

function A()  {
    this.prop = "cat";
}

A.prototype.test = function() {
    console.log(this.prop);
}

function B() {}

B.prototype.test = function(meth) {
    meth();
}

function C() {}

C.prototype.test = function(obj, meth) {
    obj[meth]();
}

var a = new A();
var b = new B();
var c = new C();

//tests
b.test(a.test);     // undefined
c.test(a, 'test');  // cat
4

2 に答える 2

1

文字列を渡す必要はありません。関数を渡すこともできます:

C.prototype.test = function(obj, meth) {
    meth.call(obj);
}

// ...

c.test(a, a.test);  // cat

Function#callthisあなたが与える最初の引数になるように呼び出し内で明示的に設定する関数を呼び出しますcall。( ; もありFunction#applyますが、唯一の違いは、関数に追加の引数を渡す方法です。)

しかし、通常 (常にではありません)、これは呼び出し元の問題と見なされ、通常は ( Function#bindES5 対応エンジン上または shim を使用して) 次のいずれかを使用して解決します。

c.test(a.test.bind(a));

...またはクロージャーを使用する:

c.test(function() {
    a.test();
});

...どちらの場合も、meth()内で呼び出すだけC.prototype.testです。

Function#bindthis呼び出されると、渡された値に設定された元の関数を呼び出し、bindその新しい関数を返す新しい関数を作成します。

私のブログの関連記事:

于 2013-11-10T12:47:11.010 に答える
1

からコピー: https://stackoverflow.com/a/16063711/1641941

この変数

すべてのサンプル コードthisで、現在のインスタンスを参照しています。

this 変数は実際には呼び出し元のオブジェクトを参照し、関数の前にあるオブジェクトを参照します。

明確にするために、次のコードを参照してください。

theInvokingObject.thefunction();

これが間違ったオブジェクトを参照するインスタンスは、通常、イベント リスナー、コールバック、またはタイムアウトと間隔をアタッチする場合です。次の 2 行のコードではpass、関数を呼び出していません。関数の受け渡しは:someObject.aFunctionであり、呼び出しは:someObject.aFunction()です。値は、関数が宣言されたオブジェクトを参照するのthisではなく、関数が宣言されたオブジェクトを参照しますinvokes

setTimeout(someObject.aFuncton,100);//this in aFunction is window
somebutton.onclick = someObject.aFunction;//this in aFunction is somebutton

this上記のケースで someObject を参照するには、関数の代わりにクロージャーを直接渡すことができます

setTimeout(function(){someObject.aFuncton();},100);
somebutton.onclick = function(){someObject.aFunction();};

クロージャー スコープに含まれる変数を細かく制御できるように、プロトタイプでクロージャーの関数を返す関数を定義するのが好きです。

var Hamster = function(name){
  var largeVariable = new Array(100000).join("Hello World");
  // if I do 
  // setInterval(function(){this.checkSleep();},100);
  // then largeVariable will be in the closure scope as well
  this.name=name
  setInterval(this.closures.checkSleep(this),1000);
};
Hamster.prototype.closures={
  checkSleep:function(hamsterInstance){
    return function(){
      console.log(typeof largeVariable);//undefined
      console.log(hamsterInstance);//instance of Hamster named Betty
      hamsterInstance.checkSleep();
    };
  }
};
Hamster.prototype.checkSleep=function(){
  //do stuff assuming this is the Hamster instance
};

var betty = new Hamster("Betty");
于 2013-11-10T17:32:57.917 に答える