javascriptという言語は、長い間、「遅い」とか「だるい」とか「しょぼい」とか「超簡単」とかいうレッテルを貼られ続けてきました。
今までは、処理の大半をサーバー側のjavaとかC言語で処理して、クライアント側では入力されたデータをサーバー側に送って、サーバー側から送られてきたデータを表示するだけというのが一般的でした。なので、サーバー側で動作するJavaとかが重要視されて、クライアント側のjavascriptは軽~~~~い扱いしかされませんでした。
ところが、HTML5やCSS3、Ajaxといった技術が登場し、クライアント側でできる事が格段に増えました。なので、これからのシステムは、サーバー側ではデータベースとのデータのやり取りだけを担当して、あとの処理は全てクライアント側で処理するという形に移行しつつあります。
そうした流れの中で、必然的にJavascriptへ注目が集まるようになりました。なぜなら、サーバー側で動作する言語は、Java, C#, C++, PHP, Rubyなどいくつもありますが、クライアント側で動作する言語は、Javascriptだけなのですから。そして、長い間バカにしてきたJavascriptという言語が、実は、知れば知るほど奥の深いすばらしい言語という事がわかってきました。これまでは、手放しでJavaのような「オブジェクト指向型」の言語が良くて、Javascriptのような「関数型」の言語は時代遅れと決め付けられてきましたが、ここに来て、「関数型」言語の奥深さが再認識されています。
Javascriptの良さは、何と言っても自由度が高いという事だと私は思っています。JavaやC#は、誰が書いても似たようなコード記述になります。それが、良さでもあるんですが、そこには、開発者のアイデアや発想が入り込む余地が少ないです。
そうした、Javascriptの特性を生かして、編み出した(盗んだ)便利技を、暇を見つけてはちょこちょこあげていけたらと思います。
Index
HTMLテンプレート
たとえば、上記のような表を表示したいとします。その場合、だいたい以下のようなコードを書いている人が多いと思います。
<body>
<div id="test">
</div>
<script>
$(function(){
var data = [];
data.push({name: "バース",no: 44});
data.push({name: "掛布",no: 31});
data.push({name: "岡田",no: 16});
var html = "";
html+='<table>';
html+='<thead>';
html+='<tr>';
html+='<th>名前</th>';
html+='<th>背番号</th>';
html+='</tr>';
html+='</thead>';
html+='<tbody>';
for (var i=0; i<data.length; i++){
html+='<tr>';
html+='<td>' + data[i].name + '</td>';
html+='<td>' + data[i].no +'</td>';
html+='</tr>';
}
html+='</tbody>';
html+='</table>';
$('#test').html(html);
});
</script>
</body>
これ、結構だるいんでよね。コードも見づらいです。最近のトレンドはこうです(以下)。
<body>
<div id="test">
</div>
<script id="template_test" type="text/html">
<table>
<thead>
<tr>
<th>名前</th>
<th>背番号</th>
</tr>
</thead>
<tbody>
<% for (var i=0; i<data.length; i++){ %>
<tr>
<td><%= data[i].name %></td>
<td><%= data[i].no %></td>
</tr>
<% } %>
</tbody>
</table>
</script>
<script>
$(function(){
var data = [];
data.push({name: "バース",no: 44});
data.push({name: "掛布",no: 31});
data.push({name: "岡田",no: 16});
var compiled = _.template($('#template_test').html());
$('#test').html(compiled({data: data}));
});
</script>
</body>
これならコードもすっきりして見やすいですね。'<script id="template_test・・・'の部分を部品のように扱っています。
そして、<%= ・・・ %>に表示したい変数を入れ込み、<% ・・・ %>の部分にfor文などのJavascriptのコードを入れ込んでいます。これは、underscore.jsのtemplate機能を使っています。
テンプレートエンジンは他にもいろいろあるので(JavaScriptテンプレートエンジンまとめ)、使いやすいのを選んで使ってもらえばいいと思います。
上記のテクニックは、別にテンプレートエンジンを使わなくても、自分で文字列置換とかでも使えます(for文とかは入れれませんが)。
Swap(値の交換)
Javascriptには、変数の値を交換する命令はありません。なので、通常は以下のような記述をします。
var a="A"; var b="B"; var work = a; a = b; b = work;
安心してください(はいてます)。こんなテクニックを考えた人がいます。
var a="A"; var b="B"; a = [b, b = a][0];
「It's a Javascript World!」
コード記述の工夫
今までJavascriptは、あくまでHTMLの補助的な役割しかなかったので、あんまり気にする人はいなかったんですが、ウェブビューのように、ほぼ全ての処理をJavascriptで書くような場合は、すぐにコードがぐちゃぐちゃになって、どこに何を書いたのかわからなくなります。
また、普通のWebページと違い、ウェブビューでは画面遷移にアニメーションで動きを付けるため、本当に画面遷移せずに、ページが切り替わる都度、AjaxでページのHTMLを読み込んで擬似的に画面遷移させる方法が一般的です。そのため、全てのページのJavascriptを一旦全て読み込んだ上で動作させています。なので、すぐに関数名や変数名がバッティングしてバグの元になったりします。そこでいろいろい工夫が必要になってきます。
ちなみに、KAZUsoftwareで一番大規模なアプリ「POOL TIGER」では、ボップアップ画面も含め、画面ごとのjsファイルが70弱あります。普通に組んで、関数や変数名を被らないでつけるれるとしたら、神業レベルです。
1.機能ごとにまとめる
機能ごとに記述場所をわけておくと、あとで目的のコードを見つけやすいです。上記はあくまで一例なので、機能の分類方法は、自分なりに工夫してください。
2.オブジェクトに内包してしまう
「tigers」というオブジェクト(変数と考えてもらっていい)の中に埋め込んでしまう方法です。この「tigers」がJavaとかで言うところのネームスペースの役割を果たします。画面ごとに「braves」とかにすれば、他の画面と名前がかぶりません。
いちいち「tigers.」という文字が前に付くので、面倒に感じるかもしれませんが、どんどんプログラムの規模が膨らむにしたがって、関数名や変数名がバッティングしてしもう事を考えれば、後々、この方が楽だと気づきます。
ただ、「function xxxx(){...}」は関数なので、いつ・どこからでも呼べますが、「tigers.xxxx = function(){...}」は厳密には、変数扱いなので、このコードが読み込まれる前に呼ばれてもUndefinedになります。変数宣言する前に、変数を呼ぶようなものと思ってもらえば、わかりやすいと思います。
なので、onReadyイベントのようなしょっぱなによばれる処理は、「function xxx{...}」で書いたりする工夫が必要です。
同じ理屈で、下図のような書きかたをする人も多いです。どちらを選ぶかは、あくまで趣味の問題です。
デフォルトパラメーター
Javascript特有の記述だと思います。
関数のパラメータが省略されている場合の、デフォルト値の設定方法です。
この例では、「team」というパラメータが呼び出し元で欠けていますが、呼び出し先でデフォルト値として「阪神タイガース」が入ります。
大変便利なテクニックですが、注意が必要なのは、このやり方だと未定義の場合だけでなく、数値の0や真偽地のfalseの場合もデフォルト値に設定されてしまう事です。
言語判定
ブラウザの設定を読み込む事によって、ユーザーの言語環境を判定するコードです。ウェブビューでもWebページでも使えます。
var language = window.navigator.userLanguage || window.navigator.language || window.navigator.browserLanguage;
if (language.indexOf("ja")>=0){
alert("日本語");
}
ちなみに、私の検証用Android端末では、インストール直後は、なぜかen(英語)になりました。Androidは謎が多いです。
チェックボックスやラジオボタンを大きくする
チェックボックスやラジオボタンは、font-sizeやwidthで大きさを変えれませんが、モバイル端末で表示する場合、ブラウザ標準UIだとちょっと小さすぎるので、以下のCSSで大きくできます。
/* 大きさ2倍 */
#chkbox{
-webkit-transform-origin: center middle;
-webkit-transform: scale( 2 , 2 );
}
金額(3桁区切り)フォーマット
Angular.jsなどは金額フォーマットの機能がありますが、これを自分で実装するのは結構骨がおれます。
しかし、最近のjavascriptは標準でメソッドが用意されています(古いブラウザでは非対応、iOSは非対応でした)。
var num = 123456789 num.toLocaleString()
→ 123,456,789
