问题提出:
将
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、判断代码段是否属于脚本,这个正则表达式的写法决定了你调用的时候该如何调用
参考文章:http://www.gbtags.com/gb/share/2587.htm