JavaScript の this, call/apply, callback のメモ

具体的には Sencha Touch 2 がきつい

とはいえ仕事でちゃんとJSかいた経験って思えばないわけで*1、だいぶ学んだ。ハマったところとわかったところをメモる。

this について

最近 JavaScriptのthisの覚え方 - Qiita [キータ] がおそらくのきっかけで this についていろいろ燃えているっぽいけど(JavaScriptのthis - Write and Run とか JavaScript の this キーワードに結びつけられる値はどのように決定されるのか (言語仕様の説明) - ひだまりソケットは壊れない とか)、それに便乗しているわけではない。

正直あまりいまもちゃんと理解できているわけではないから debugger を仕込みながら確認している。無意識的にはかけない。まずは 第16回 JavaScriptのthisとcall:これでできる! クロスブラウザJavaScript入門|gihyo.jp … 技術評論社 の @os0x さんの記事で「 this は関数実行時に呼ばれたオブジェクト(なので定義時にきまるわけではない)」というのを鵜呑みにしてどうにか仕込んでやっている。で、呼ばれた function がいくらかネストしてたり callback してたりリスナーはってたりするときに this が変わってしまうから、self とか Sencha だと me に bind している。CoffeeScript だと-> ではなく => で簡単に定義とある。bindについてはあまりまだ実感がないけど、thisがいろいろ変わってしまって不便だから一時的に格納してどうこうするというのがよくあるパターン。

callback について

ってのは、まあ以前に一度かいた callback関数ってのがわかったようなわからないような話 - atas 。つまり「returnで同期的に実行されるわけじゃない。あとで行われる function」とある。とは頭でわかっていたつもりだけど、実装するとなるとまず Ext.Ajax.request みたな $.ajax みたいなところでコールバックがあるし、そうでなくてもいろんなところで Ext.hogefunc(callback, scope)とかよくある。で、コールバック関数を実行するときに上記の this の bind をしたりとかなんかある。

JSONPでかえってくるコールバック関数ってのも、「一度リクエスト要求したらあるJSONファイルが hogefunc({JSON})でかえってくるから、そのまま hogefunc が実行されるよね」ということでしかない(という理解)。非同期で呼び出して〜ってあたりがまさにTwitter API をたたいたあたりがわかってなくて、ローカルのファイルに「hogefunc({JSON})」ってのが定義されてたらまあそりゃそのまま呼び出しますよね、という。

しかし Defferd とか Promise とかになってくるとさすがによくわからない。まあ、いまはいいや

追記

JavaScriptとコールバック地獄 - Yahoo! JAPAN Tech Blog
という記事がつい最近あったけど、「同期か非同期か」ってのがすごくポイントで、それでうまく理解できていなかった気がする。コールバック関数 = あとでやるということは、非同期になる。XMLHttpRequest とか setTimeout は、非同期になる。だから、thisとかをバインドしたりする。そういう意味では Deferred オブジェクトをつくり, Resolve か Reject という状態にして、Promise で返す。それを then でつなげる。なのかな?

call, apply

これも頭では「なんか実行するオブジェクトとメソッドが逆になってなんかこうメソッドを便利に使いたいらしいね」くらいの理解だったが、JavaScriptのthisの覚え方 - Qiita [キータ] のコメントがわりとしっくりきた。
ありがちなパターンとしては DOM をとってきたけど型が Array ではなくて Nodelist だから Array に変換してよしなにしたいねってときに以下のパターンとかよくある。

var ary = Array.prototype.slice.call(document.getElementsByClassName("hoge"))

Sencha 内部でもこの call をしまくっていたソースがあって、どれかは忘れちゃったけど return hoge.call(me, null, options) とかなんとかしてたりする。

まあ

頭で予習しているのはある程度役に立つけど、実装しないと挙動よくわからんね。この件が終わったらパーフェクトJavaScriptとか読んでみようかなぁとか思った。頭で知って、泥臭くデバッガしこんで、もう一度本を読む。

*1:ほんのちょっとしたUIをjQueryでかいたくらい

広告を非表示にする