- # プログラミング全般 > JavaScript
JavaScriptのテンプレートエンジンの仕組みを解読してみる
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
Latest topics > PHPとかerbのようなテンプレートをJavaScriptで。 – outsider reflex という記事を見つけて、JavaScriptでのテンプレートエンジンのコードが書いてあった。
パッと見で理解できないので、1行づつ順を追って解読を試みてみたメモです。
function parseTemplate(aCode, aContext) { var __parseTemplate__codes = []; aCode.split('%>').forEach(function(aPart) { var strPart, codePart; [strPart, codePart] = aPart.split('<%'); __parseTemplate__codes.push('__parseTemplate__results.push('+ strPart.toSource()+ ');'); if (!codePart) return; if (codePart.charAt(0) == '=') { __parseTemplate__codes.push('__parseTemplate__results.push(('+ codePart.substring(1)+ ') || "");'); } else { __parseTemplate__codes.push(codePart); } }); var __parseTemplate__results = []; with(aContext|| {}) { eval('(function() { '+__parseTemplate__codes.join('\n')+' }).call(aContext|| {})'); } return __parseTemplate__results.join(''); } var source = <![CDATA[ 大切な事なので3回言います。 <% for (var i = 0; i < 3; i++) { %> 今日は<%= today %>です。 <% } %> オーケー? ]]>.toString(); var params = { today : (new Date()).toString() }; var result = parseTemplate(source, params);
まずは、テンプレート部分のソースのみ抜き出す。
大切な事なので3回言います。 <% for (var i = 0; i < 3; i++) { %> 今日は<%= today %>です。 <% } %> オーケー?
以下、少しずつ解読して行きました。
1.aCode.split('%>') により・・・
①大切な事なので3回言います。\n<% for (var i = 0; i < 3; i++) {
②\n今日は<%= today
③です。\n<% }
④\nオーケー?
に分割される。
2.forEachの中で、[strPart, codePart] = aPart.split('<%'); により
strPart codePart ① "大切な事…\n" " for (var i = 0; i < 3; i++) { " ② "今日は" "= today " ③ "です。\n" " }" ④ "\nオーケー?" ""
に分割される。
3.forEachで回し、__parseTemplate__codesを組み立てる。
__parseTemplate__codes には・・・
①'__parseTemplate__results.push(' + strPart.toSource() + ');' という文字列がpushされる。
②codePartに"="(変数での置き換え)が含まれる場合、
'__parseTemplate__results.push((' + codePart.substring(1) + ') || "");' という文字列がpushされる。
③含まれない場合、codePartの文字列がそのままpushされる。
4.strPart, codePart の中身は、
strPart codePart ① "大切な事…\n" " for (var i = 0; i < 3; i++) { " ② "今日は" "= today " ③ "です。\n" " }" ④ "\nオーケー?" ""
であるから、_parseTemplate__codes の配列構造は・・・
_parseTemplate__codes = [ '__parseTemplate__results.push("大切な事…\n");', ' for (var i = 0; i < 3; i++) { ', // ① '__parseTemplate__results.push("今日は");', '__parseTemplate__results.push(today);', // ② '__parseTemplate__results.push("です。\n");', ' }', // ③ '__parseTemplate__results.push("\nオーケー?");', '' // ④ ]
という配列が作られる。
5.文字列を組み立てて、evalされる。
__parseTemplate__codes.join('\n') により、
__parseTemplate__results.push("大切な事なので3回言います。\n"); for (var i = 0; i < 3; i++) { __parseTemplate__results.push("今日は"); __parseTemplate__results.push(today); __parseTemplate__results.push("です。\n"); } __parseTemplate__results.push("\nオーケー?");
という文字列が作成され、これがevalされる。
evalは、with(aContext|| {}) により、与えられたコンテキスト(オブジェクト)の中で行われる。(todayは、params.todayとして評価される。)
6.__parseTemplate__results は・・・
["今日は", today(を評価した内容), "です。\n", "今日は", today(を評価した内容), "です。\n", "今日は", today(を評価した内容), "です。\n",]
という配列構造となる。
これをjoin('')でつないでreturn。
以上、テンプレートエンジンがどんな仕組みで動くのかを知ることが出来ました。
実際に動くかどうかも試してみる。
- - 関連記事 -
- グローバル変数を上書きしてしまうJavaScriptコードのthisを確認する
- JavaScriptでnewを忘れるとグローバル変数を上書きしてしまう
- JavaScriptテンプレートエンジンを動かしてみる
- IEのinnerHTMLにはscriptタグを含んではダメだって
- JavaScriptとPHPの変数スコープの違い
- FizzBuzzをJavaScriptで書いてみた