コールバック関数のメモ(引数やthis) : JavaScript

Pocket

コールバック関数の注意点などをメモ。

コールバック関数を使う場面

  • setTimeout
  • イベントリスナー addEventListener
  • jQueryのメソッド(animateなど)[1]

[1] animate( properties [, duration] [, easing] [, complete] )のcompleteはアニメーションが完了したら実行するコールバック関数。
» .animate() – jQuery API

コールバックで注意する点

  • コールバック関数への引数の渡し方
  • コールバック関数内でのthis

コールバック関数への引数の渡し方

setTimeout

setTimeout(callback, 1000, arg1, arg2)のようにコールバック関数の引数をsetTimeoutの引数として渡せるブラウザが多い。
» window.setTimeout – MDN

しかし対応していないブラウザもある。下記のような対策がある。

対策1

コールバック関数をクロージャーにする。

function callback(name) {
    return function() {
        console.log('Hello, ' + name);
    }
}
setTimeout(callback('foo'), 1500));
// Hello, foo
対策2
setTimeout('callback("' + arg1 + '", "' + arg2 + '")';

対策2は下記の点に注意する。
a.引数をクォートで囲む必要がある
b.オブジェクトを引数に渡せない(エラー missing ] after element list)

対策3

Function.prototype.applyを使う。

// http://wiz-code.digick.jp/blog/?p=711
function curryTimerCallback() {
    var userFunc = arguments[0],
        args = Array.prototype.slice.call(arguments, 1);
    return function() {
        return userFunc.apply(this, args);
    };
}
// 対策1とことなりクロージャーではない。
function callback(name) {
    console.log('Hello, ' + name);
}
setTimeout(carryCallbackTimer(callback,'baz'), 1500));

addEventListner

» element.addEventListener – MDN

target.addEventListener(type, listener, useCapture);
target.addEventListener(type, listener, useCapture [, aWantsUntrusted     非標準 ] ); // Mozilla only

addEventListenerの引数にはsetTimeoutのようにコールバック関数の引数を指定できない。対策はsetTimeoutと同じ。

jQueryメソッド

jQueryのメソッドはsetTimeoutやaddEventListenerのようにコールバック関数をクロージャーにしなくてもうまく動作する。

function callback(name) {
    console.log('Hello, ' + name);
}
elem.animate({
    left: 100;
}, 500, callback('foo'));

Appendix

jQueryメソッドで複数のコールバック関数を引数にとる場合の書き方。

» jsFiddle

// hover
elem.hovera(function() {
    $(this).addClass('mouseover');
}, function() {
    $(this).removeClass('mouseover');
});

コールバック関数内のthis

コールバック関数内のthisはwindow。対策はthisとして使うオブジェクトを引数で渡す。

jsFiddle

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。