レキシカル変数を意識した jQuery プログラミング
こんにちは、ktanakaです。今日はjQueryを利用したら無意識に使っているかもしれないレキシカル変数についてとりあげます。まず、jQueryを利用したコードを示し、それをレキシカル変数を利用したコードに書き直します。
jQuery で click して toggle するコード
とりあえず、レキシカル変数とは何か?という話は置いて、 jQuery を利用したコードを示します。
index.html
<html>
<head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="program.js"></script>
</head>
<body>
<p><input type="button" id="trigger" value="ボタン" /></p>
<div class="target">トグルしたいもの</div>
</body>
</html>
ボタンとボタンを押す毎にトグルさせたい対象があるとします。
program.js
// (1)
$(document).ready(function(){
// (2)
$("input#trigger").click(function(){
// (3)
$("div.target").toggle();
});
});
このプログラムは、ボタンをクリックする毎に div#target の表示/非表示が切り替わるというものです。この処理を詳しく説明すると、
- ドキュメント (DOM) の準備が整ったら、次の関数を実行する ...(1)
- input 要素 (id が trigger) がクリックされたら、次の関数を実行する ...(2)
- div 要素(class が target) を toggle する ...(3)
となります。ここでプログラマーにとっては気になる部分があります。それは3番のコードです。なぜかというと、ボタンがクリックされるたびに、ドキュメント全体から、"div.target" に当てはまる要素をかき集める仕事をjQueryにさせているからです。このサンプルでは、要素の数も少なく、クエリもシンプルなので大事には至りませんが、要素が増えたり、クエリが複雑だと、動作がもっさり?するかもしれません。
$("div.target") をあらかじめ変数に代入しておく
さて、 HTML や JavaScript を調査した結果、 program.js が実行されたあとに、$("div.target") に該当する要素が増えたり減ったりしないことがわかりました。そのときは次のように書き換えることができます。
$(document).ready(function(){
var target = $("div.target"); // (4)
$("input#trigger").click(function(){
target.toggle(); // (5)
});
});
変更されたコードでは、あらかじめ toggle させる要素をとりだし(4)、ボタンがクリックされたときは、既に用意されている変数 target にたいして toggle させることでページ全体を検索する手間を省いています。
変数 target
さて、修正されたコードを見ると、不思議なことが起きていると思われる方がいるかもしれません。 $(document).ready( ... ) の関数はドキュメントの読み込み後に一度だけ実行されるわけだから、関数の実行が終わったら変数 target も利用できなくなっているはず!ということです。
関数の入れ子とレキシカル変数
変更したJavaScriptのコードを見ると、関数が2つ定義されていて、入れ子の関係になっています。(↓で関数の外側を強調してみました)
$(document).ready(function(){
var target = $("div.target");
$("input#trigger").click(function(){
target.toggle();
});
});
そして、内側の関数のなかから、外側の関数のローカル変数にアクセスしています。関数の処理が終わっても変数にアクセスできるのです。変数 target はグローバルから直接アクセスできません。しかし、内側で定義された関数からは、処理が終了してもアクセスできます。このような変数をレキシカル変数と言います。
まとめ
- jQueryを利用したコードを変更しながらレキシカル変数について説明しました
- jQueryを利用したコードでは関数の入れ子の形が上記のようによくでてきますので無意識にレキシカル変数を使っているかもしれません
JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス 水野 貴明 オライリージャパン 2008-12-22 売り上げランキング : 5984 おすすめ平均 Amazonで詳しく見る by G-Tools |