2

私はこの特定の問題を回避する方法を知っていますが、なぜそれが起こるのか知りたいです。基本的に、次のような関数を呼び出そうとすると、次のようになります。

(callFoo ? this.foo : this.bar)();

正しいfoo関数を呼び出しますが、fooの内部は、this私が期待するオブジェクトではなく、グローバルなウィンドウオブジェクトです。

私はこれが同じことをすることを期待しますが、そうではありません:

(this.foo)();

上記のコードは正しい関数を呼び出し、正しいコンテキストを維持します(this私が期待しているものです)。

これがあなたがいじくり回すためのjsfiddleです。

誰かが何が起こっているのか説明してもらえますか?問題を回避する方法は理解していますが(私はその構文のファンでさえありません)、this三項演算子から関数を返すとなぜウィンドウになるのかを知りたいです。


編集
私は私の質問を洗練したいと思います:これは私にとって理にかなっています:

(callFoo ? this.foo : this.bar)();

と同等です:

var f = (callFoo ? this.foo : this.bar);
f();

thisそして、なぜその関数内のウィンドウになるのかは私には理にかなっています。

ここで同じことが起こらないのはなぜですか。

(this.foo)();
4

4 に答える 4

2

正しいコンテキスト呼び出しオブジェクトを取得するには、次のように呼び出します。

this[ callFoo ? 'foo' : 'bar' ]();

の値は、this常に関数の呼び出し方法によって異なります。基本的には次のように関数を呼び出しています

fnc();

これにより、this常にグローバル/ウィンドウになります(非厳密モード)。のようなメソッド/プロパティとして関数を呼び出す必要がありますthis.fnc()。その場合、thisデフォルトで呼び出しのオブジェクトを参照します。

于 2012-10-04T21:23:26.007 に答える
1

この式は、論理的に次のようなものと同等です。

var tempFun;
if(callFoo) {
    tempFun = this.foo;
} else {
    tempFun = this.bar;
}
tempFun();

これは、参照を失う典型的な例ですthis。あなたが言ったように、あなたは回避策/解決策を知っています:

tempFun.call(this);

また:

(callFoo ? this.foo : this.bar).call(this)
于 2012-10-04T21:31:36.123 に答える
1

不一致の理由:

var obj = new (function MyConstructor(){
    this.getConstructor = function(){ return this.constructor.name; }
});

オペランドが任意の演算子によって操作される場合、結果は関数の戻り値とほとんど同じように機能します。渡されたオブジェクトメソッドは、オブジェクトに関連付けられているように扱われなくなりました。

(function(){ return obj.getConstructor; })(); //'Window'

ただし、プロパティアクセス以外にパレン内で何も起こらない場合、パレンは演算子自体として扱われるのではなく、単に無視されます。それで:

(obj.getConstructor)(); //'MyConstructor'

本当に同等です:

obj.getConstructor();

ただし、次のような結果になる任意の種類の有効な操作を追加します。

(false || obj.getConstructor)(); //'Window'

また、obj.getConstructorは、「。」を介してオブジェクトに関連付けられたメソッドではなく、渡されたメソッドとして扱われます。協会。

于 2012-10-04T21:54:26.417 に答える
0

三項演算子を使用する場合、2つの関数から選択します。これは、次のようなことを行うのと似ています。

var func = this.foo;
foo(); // Inside this call, "this" will now refer to the global context
       // -- "window" in a browser environment

これ(つまり、「これ」)はJavaScriptの大きなトリッキーなものの1つであり、多くのことが書かれています。

「this.foo」の周りに親を投げても問題が発生しないのは少し驚きです。しかし、それはあなたの質問ではありませんでした:-)

于 2012-10-04T21:30:22.347 に答える