之前就和javascript模板引擎打过交道,也大致了解是什么原理,但是没有实际的去探究过。今天在一个开源的cmf项目中发现了一个类似模板引擎的东西,只有短短的20行,顿时吸引了我兴趣,奉上源码:
// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
var cache = {};
this.tmpl = function tmpl(str, data){
// Figure out if we're getting a template, or if we need to
// load the template - and be sure to cache the result.
var fn = !/\W/.test(str) ?
cache[str] = cache[str] ||
tmpl(document.getElementById(str).innerHTML) :
// Generate a reusable function that will serve as a template
// generator (and which will be cached).
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};" +
// Introduce the data as local variables using with(){}
"with(obj){p.push('" +
// Convert the template into pure JavaScript
str
.replace(/[\r\t\n]/g, " ")//去掉空格符
.split("<%").join("\t")//<% 替换成 \t制表符
.replace(/((^|%>)[^\t]*)'/g, "$1\r")//
.replace(/\t=(.*?)%>/g, "',$1,'")
.split("\t").join("');")
.split("%>").join("p.push('")
.split("\r").join("\\'")
+ "');}return p.join('');");
// Provide some basic currying to the user
return data ? fn( data ) : fn;
};
})();
看不太明白?幸好源码中有这段代码的来源,打开链接后发现是竟然是“jQuery之父” John Resig大神写的,赶紧拜读一下啊。
点我
过去我一直以为要在javascript引擎中实现有如if/else,for等语句需要写很多的代码,我也觉得这点代码不能做到这些,但是却打了我的脸。
它的原理简单来说就是把字符转转换成了纯javascript可执行语句,中间采用了字符串和数组的相互转换来过渡。举个例子:
模板代码:
<% for ( var i = 0; i < users.length; i++ ) { %>
<li><a href="<%=users[i].url%>"><%=users[i].name%></a></li>
<% } %>
转换成了javascript语句:
for ( var i = 0; i < users.length; i++ ) {
'<li><a href="' +users[i].url '">' + users.name +' </a></li>'
}
具体的解析可以看这个英文的解析 这里
小结
- 使用了Funtion,字符串和数组转化,with关键字
- 这大概就是技(zhi)术(shang)之美吧。