[自制模板引擎] 为模板引擎增加解析表达式功能
通过上一片已经能把占位符替换成对应的变量的值,实现了一个简单的迷你模板引擎,模板引擎一个不错的功能就是能够计算一些简单的表达式,计算表达式的核心其实就是执行字符串,执行字符串的方法多种多样eval,Function,setTimeout等等,都能执行,至于用哪种方法,就仁者见仁智者见智了。
下面整理一下在模板引擎中会遇到的表达式:
{ a + b } //普通的计算表达式 { a == false } //普通的比较 { a === false } //全等比较 { a !== false} { !a } //非运算 ……
普通表达式,非运算,比较
这三种表达式,无非就是替换其中的变量,然后判断一下是否为数字,最后执行一遍这个字符串便能直接解析出这段表达式,所以下面解析出这几种运算符。
//替换一个表达式内的运算符 var m = " 1 + 2 + 3 - 1 + test"; var obj = { test : 1 }
//处理运算符的值
//这里简单的处理了加减操作 m = m.replace(/[^\+-\s]*/g,function(varMatch) { //如果是不是数字 //并且在对应的对象有这个属性 if (Number(varMatch) != Number(varMatch) && obj[varMatch]) { if (typeof obj[varMatch] === "number") { return obj[varMatch]; }else{ return "'" + obj[varMatch] + "'"; } }else{ return varMatch; } }); console.log(m);
不管用什么方法,解析表达式必须要执行字符串表达式,所以方法千万种,目的只有一个,下面是一个完整的可执行的解析表达式的例子。
var originalData = { jquery : "hello jquery", angular : " two-way data binding", react : "The Fast and the Furious" } var text = "我喜欢{{jquery + angular}},但是最近几年{{angular == angular}}貌似是一个方向,但是又有了{{react == false}},让我犹豫了我是否应该报考蓝翔学习{{1+1}}" activeExpresstion(text,originalData); function activeExpresstion(text,obj){ var operatorReg = /[\+-\/\*\=\!]*/g; var variableReg = /[^\+-\/\*=\!\s]+/g; var placeReg = /\{\{.*?\}\}/g; var expressValue;
//取出每一组{{}}包含的占位符 text = text.replace(placeReg,function(m){ m = m.substring(2,m.length-2); //判断是否有运算符 if (operatorReg.test(m)) { m = m.replace(variableReg,function(varMatch) { //如果是不是数字 //并且在对应的对象有这个属性 if (Number(varMatch) != Number(varMatch) && obj[varMatch]) { if (typeof obj[varMatch] === "number") { return obj[varMatch]; }else{ return "'" + obj[varMatch] + "'"; } }else{ return varMatch; } }) eval("expressValue = " + m); return expressValue; }else { if (obj[m]){ return obj[m] }else{ return m; } } }); return text; }