コンテキストをどのように渡すのsetTimeout
ですか?1000ms後this.tip.destroy()
なら電話したいthis.options.destroyOnHide
です。どうやってやるの?
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
上記を試すとthis
、ウィンドウを指します。
コンテキストをどのように渡すのsetTimeout
ですか?1000ms後this.tip.destroy()
なら電話したいthis.options.destroyOnHide
です。どうやってやるの?
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
上記を試すとthis
、ウィンドウを指します。
回答:
編集:要約すると、この問題がこの問題を解決する最も一般的な方法が尋ねられた2010年に戻って、グローバルオブジェクトをポイントして関数を実行するsetTimeout
ため、関数呼び出しが行われるコンテキストへの参照を保存することでした:setTimeout
this
var that = this;
if (this.options.destroyOnHide) {
setTimeout(function(){ that.tip.destroy() }, 1000);
}
その1年前にリリースされたばかりのES5仕様では、bind
メソッドが導入されました。これはまだ広くサポートされておらず、使用するためにポリフィルが必要だったため、元の回答では提案されていませんでしたが、今ではすべての場所にあります。
if (this.options.destroyOnHide) {
setTimeout(function(){ this.tip.destroy() }.bind(this), 1000);
}
bind
関数が持つ新しい機能を作成this
価値予め充填されています。
現在のJSでは、これはまさにES6で矢印関数が解決する問題です:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy() }, 1000);
}
矢印関数にはthis
独自の値はありません。アクセスすると、それthis
を囲む字句スコープの値にアクセスします。
また、HTML5はタイマーを2011年に標準化し、コールバック関数に引数を渡すことができるようになりました。
if (this.options.destroyOnHide) {
setTimeout(function(that){ that.tip.destroy() }, 1000, this);
}
以下も参照してください。
this
関数に正しく渡された場合、この場合、map()、forEach()などで、この問題は、より少ないコード、より少ないCPUサイクル、およびより少ないメモリを使用して解決したことになります。***参照:ミシャ・レイズリンの答え。
回答済みの関数ラッパー@CMSへの既成のショートカット(構文糖)があります。(以下では、必要なコンテキストがであると想定していますthis.tip
。)
ECMA-262、第5版(ECMAScript 5)またはNode.jsと互換性のあるブラウザーをターゲットにする場合は、を使用できますFunction.prototype.bind
。オプションで関数の引数を渡して、部分的な関数を作成できます。
fun.bind(thisArg[, arg1[, arg2[, ...]]])
もう一度、あなたのケースでは、これを試してください:
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
同じ機能がプロトタイプ(他のライブラリ?)にも実装されています。
Function.prototype.bind
カスタムの下位互換性が必要な場合は、このように実装できます(ただし、注意事項に従ってください)。
最先端の開発(2015)では、ECMAScript 2015(Harmony / ES6 / ES2015)仕様の一部であるファットアロー関数を使用できます(例)。
矢印関数式(としても知られている脂肪の矢印機能は)関数式に比べて短い構文を持ち、字句バインドする
this
値を[...]。
(param1, param2, ...rest) => { statements }
あなたの場合、これを試してください:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
jQuery 1.4+をすでに使用しているthis
場合は、関数のコンテキストを明示的に設定するための既製の関数があります。
jQuery.proxy():関数を取り、常に特定のコンテキストを持つ新しい関数を返します。
$.proxy(function, context[, additionalArguments])
あなたの場合、これを試してください:
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
それはUnderscore.jsで利用できるだけでなく、lodash、として_.bind(...)
1、2
bind関数をオブジェクトにバインドします。つまり、関数が呼び出されるたびに、の値が
this
オブジェクトになります。必要に応じて、引数を関数にバインドして事前に入力します。部分適用とも呼ばれます。
_.bind(function, object, [*arguments])
あなたの場合、これを試してください:
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}
func.bind(context...)
か?私は何かを逃していますか?
var boundFn = fn.bind(this); boundFn(); boundFn();
、たとえば参照を保持することもできます。
Internet Explorer以外のブラウザーでは、遅延後にパラメーターを関数に一緒に渡すことができます。
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
だから、これを行うことができます:
var timeoutID = window.setTimeout(function (self) {
console.log(self);
}, 500, this);
これは、スコープのルックアップ(this
タイムアウト/間隔式の外の変数へのキャッシュ)、および($.proxy
またはを使用したFunction.prototype.bind
)クロージャーの作成よりもパフォーマンスの点で優れています。
WebreflectionからIEで機能させるコード:
/*@cc_on
(function (modifierFn) {
// you have to invoke it as `window`'s property so, `window.setTimeout`
window.setTimeout = modifierFn(window.setTimeout);
window.setInterval = modifierFn(window.setInterval);
})(function (originalTimerFn) {
return function (callback, timeout){
var args = [].slice.call(arguments, 2);
return originalTimerFn(function () {
callback.apply(this, args)
}, timeout);
}
});
@*/
を使用している場合はunderscore
、を使用できますbind
。
例えば
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this), 1000);
}