问题提出:
将
var template = "<p>Hello, my name is {name}. my father {age} years old.</p>";
var json = { name: "Krasimir",age:50 };
替换为:
<p>Hello, my name is Krasimir. my father 50 years old.</p>
可以这样实现:
var template = "<p>Hello, my name is {name}. my father {age.father} years old.</p>";
var json = { name: "Krasimir",age: 29 };
var tempo = function(str){
str = str.replace(/([\'|\\])/gm,"\\$1") //转义掉 \ 和 '
.replace(new RegExp('{([^{}]*)}','gim'), "'+(data.$1==null?'':data.$1)+'") //转化为包括变量的字符串
.replace(/[\n\r]/gm,'\\n'); //去除回车换行//
str = ["return '", str ,"';"].join('');
return new Function('data',str);
};
console.log((tempo(template))(json));
PS:
1、
var multFun = new Function("x", "y", "return x * y")//这段话其实等效于 function multFun(x, y){ return x*y }
2、其实该函数就是将原来的字符串str转换为:
return '<p>Hello, my name is '+(data.name==null?'':data.name)+'. my father '+(data.age.father==null?'':data.age.father)+' years old.</p>';
再使用new Function(data, str)转换为参数为data的函数
3、从实现可以看出,对于情况诸如下面,使用tempo()也是可以解决
var json = { name: "Krasimir",age: { son:29, father:50 } };
var template = "<p>Hello, my name is {name}. I\'m {age.father} years old.</p>";
但是如果包含数组怎么办呢?如果仅仅只是诸如如下的情况,很容易办,依次调用tempo函数即可:
var json = [{ name: "Krasimir",age: 23 }, { name: "Tom",age: 33 }];
tempo.prototype.replaceArray = function(str, arr){
var rtn = [];
for(var i=0,len=arr.length; i<len; i++){
var json = arr[i];
rtn[i] = (tempo(str))(json);
}
return rtn;
};
但是这还是没有做出任何本质的改变,如果情况如下,其中包含了js语句那这怎么办呢?PS:为了使得能够使用循环,我区别符{}替换为了 <% %>
var json = { name: "Krasimir",age: [ 23, 74, 56, 78 ]};
var template = "<p>Hello, my name is ,<% this.name %>. my sons ages: <% for(var index in this.age ) { %> : <% this.age[index] years old } %> .</p>";
那怎么办?我们需要什么样的字符串来构造函数呢?我想应该如下:
var r=[];
r.push("<p>Hello, my name is ,");
r.push( this.name );
r.push(". my sons ages: ");
for(var i=0,len= this.age.length; i<len; i++ ) {
r.push(" ");
r.push( this.age[i] );
r.push(" ");
}
r.push(" years old .</p>");
return r.join("");
这样的我只要运行一下这个脚本不就搞定了吗,具体实现如下:
var json2 = { name: "Krasimir",age: [ 23, 74, 56, 78 ]};
var template2 = "<p>Hello, my name is ,<% this.name %>. my sons ages: <% for(var i=0,len= this.age.length; i<len; i++ ) { %> <% this.age[i] %> <% } %> years old .</p>"
var tempo2 = function(str){
var re = /<%([^%>]+)?%>/g,
reExp = /(if|for|else|switch|case|break|{|})(.*)?/g,
code = 'var r=[];\n',
cursor = 0;
var add = function(line, js) {
js? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
(code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
return add;
}
while(match = re.exec(str)) {
add(str.slice(cursor, match.index))(match[1], true);
cursor = match.index + match[0].length;
}
add(str.substr(cursor, str.length - cursor));
code += 'return r.join("");';
console.log(code)
return new Function(code.replace(/[\r\t\n]/g, ''));
};
console.log((tempo2(template2)).apply(json2))
PS:1、Apply 方法作用更改this关键字的值,不然this == tempo2
2、判断代码段是否属于脚本,这个正则表达式的写法决定了你调用的时候该如何调用