5

関数/メソッド呼び出しのコンテキストを変更するためのメソッドの使用方法を知っています: apply、bind、call。私の質問はこれです、関数/メソッドに既にコンテキストが設定されているかどうかを確認する方法はありますか?

// given
var beta;

function alpha () {
  return this;
}

function isContextSet (fn) {
  /* check for context binding on fn */
}

beta = alpha.bind("hello");

isContextSet(alpha); // returns false
isContextSet(beta); // returns true

私はこれに対する答えをすでに知っていると思いますが、1.私の仮定を確認するか、2.何かを学ぶ以外の理由がなければ、とにかく尋ねようと思いました。この質問をするのは私が初めてではないと確信していますが、.apply()、.call()、または .apply()、.call()、または.練る()。

4

3 に答える 3

3

いいえ。

実際、バインディングをコンテキストの「変更」と呼ぶのは正しくありません。それが行うことは、ある関数を別の関数に変換し、特定のコンテキストで最初の関数を呼び出すことです。

関数はさまざまな方法でバインドできます。たとえば、自分でバインドできます。

function bind(fn,ctxt){
    return function(){
        fn.apply(ctxt,arguments);
    };
}

または、Function.prototype.bind、または同じことを行うシム、またはアンダースコアの _.bind でバインドすることもできます。コンテキストに加えて、初期引数にバインドできます。いずれの場合も、本質的に実際に関数を実行しなければ、何が起こったのかを知る方法はありません。

バインドは、ある関数を別の関数に変換する多くの方法の 1 つにすぎません。関数を変換して、今から 1 秒後に実行するか、2 回実行することもできます。バインドに魔法はありません。古い関数に基づいて新しい関数を作成するだけです。[[bound_to]] と呼ばれる特別な変数が関数に設定されていないため、調べることができます (別の回答が示唆するように、バインドの独自のカスタム実装を使用しない限り)。関数がどのように変換されたかを判断する事後的な方法はありません。

私が想像できる最も近いのは、バインドされている可能性のある関数をバインドされていないバージョンに対してチェックし、それらが等しいかどうかを確認することです。

function log_this(){console.log(this);}
var bound_func=log_this.bind(my_var);
console.log(log_this===bound_func); // FALSE
于 2013-06-22T13:52:29.603 に答える
0

できることは次のようなものです。

function f(context, whatever) {
    if(this !== context) {
        //context has been changed
    }
}

var y = f.bind(thingy);
y(otherThingy, something);

カスタムバインド関数を使用して、次のようなハックを行うこともできます。

function bind(func, context) {     
    var newFunc = func.bind(context);
    newFunc._this = context;
    return newFunc;
}

function checkContext(func, context) {
    return func._this !== context;
}
于 2013-06-22T13:50:55.710 に答える
-1

これはJavaScirptが好きな人にとって興味深い質問だと思います。これがあなたが探しているものであることを願っています:


var isContextSet = function (fn) {
   var testThis = {}; //unique object for testing what is this inside fn
   return fn.call(testThis) !== testThis;
}

これをfn内に「設定」しようとしました:fn.call(testThis);その関数が新しく作成されたオブジェクト ( testThis ) への参照を返した場合、バインドされません。私はあなたがそれを得る願っています:)

編集: これは、fnがこれを返すときに機能します(問題に示されているように)。そうしないと、isContextSet を適切に定義できません。

于 2013-06-22T13:52:54.033 に答える