- # プログラミング全般 > 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で書いてみた