nodom2

nodom2 主要完成了常见js表达式处理包括 操作符 ()!|*/+-><=&%,以及操作符组合如>=、===、!== 等,值null undefined true false。

代码结构有了很大优化,字符串处理变得更简单,分为字符串、变量和函数。

代码如下:

1class Expression{ 2 /** 3 * @param exprStr 表达式串 4 */ 5 constructor(exprStr){ 6 this.inited = true; 7 //旧值 8 this.oldVal = undefined; 9 //新值 10 this.newVal = undefined; 11 this.stack = this.init(exprStr); 12 } 13 14 /** 15 * 初始化,把表达式串转换成堆栈 16 */ 17 init(exprStr){ 18 //字符串开始 19 let startStr = undefined; 20 let type = 0; // 1字符串 2变量 3函数 21 //字符串开始结束符 22 let strings = "'`\""; 23 //运算符 24 let operand = "()!|*/+-><=&% "; 25 // 26 let values = ['null','undefined','true','false']; 27 //堆栈 28 let stack = new Array(); 29 let sTmp = ''; 30 for(let i=0;i<exprStr.length;i++){ 31 let c = exprStr[i]; 32 switch(type){ 33 case 1: //当前为字符串 34 //字符串标识 35 if(strings.indexOf(c) !== -1){ 36 if(c === startStr){ 37 this.addStr(sTmp + c,stack); 38 startStr = undefined; 39 sTmp = ''; 40 type = 0; 41 continue; 42 } 43 } 44 break; 45 case 2: //当前为变量 46 //操作符 47 if(operand.indexOf(c) !== -1){ 48 //转为函数 49 if(c === '('){ 50 type = 3; 51 }else{ //变量结束 52 this.addVar(sTmp,values,stack); 53 sTmp = ''; 54 type = 0; 55 } 56 } 57 break; 58 case 3: 59 if(c === ')'){ 60 let a = sTmp.trim().split('('); 61 //函数名 62 let fn = a[0]; 63 //参数 64 let pa = a[1].split(','); 65 for(let j=0;j<pa.length;j++){ 66 pa[j] = pa[j].trim(); 67 } 68 69 //函数入栈 70 stack.push({ 71 val:fn, 72 params:pa, 73 type:'function' 74 }); 75 sTmp = ''; 76 type = 0; 77 continue; 78 } 79 break; 80 default: 81 //字符串开始 82 if(strings.indexOf(c) !== -1){ 83 startStr = c; 84 type = 1; 85 }else if(operand.indexOf(c) === -1){ //变量开始 86 type = 2; 87 if(sTmp !== ''){ 88 this.addStr(sTmp,stack); 89 sTmp = ''; 90 } 91 } 92 } 93 sTmp += c; 94 } 95 if(type === 2){ //变量处理 96 this.addVar(sTmp,values,stack); 97 }else if(type === 0 && sTmp !== ''){ //字符串 98 this.addStr(sTmp,stack); 99 }else{ 100 //抛出表达式错误 101 throw DD.Error.handle('invoke','expression',0,'Node'); 102 } 103 return stack; 104 } 105 106 107 108 /** 109 * 表达式计算 110 * @param module 模块 111 * @param model 模型 112 */ 113 val(module,model){ 114 if(this.stack === null){ 115 return ''; 116 } 117 let retStr = ''; 118 this.stack.forEach((item)=>{ 119 let value=''; 120 switch(item.type){ 121 case 'string'://字符串 122 value = item.val; 123 break; 124 case 'field'://变量 125 value = model.$get(item.val); 126 break; 127 case 'function'://函数 128 let foo = module.methodFactory.get(item.val); 129 if(DD.isFunction(foo)){ 130 let param = []; 131 if(item.params.length>0){ 132 item.params.forEach((p)=>{ 133 param.push(model.$get(p)); 134 }); 135 } 136 value = foo.apply(module,param); 137 } 138 } 139 retStr += value; 140 }); 141 142 if(retStr !== ''){ 143 retStr = eval(retStr) + ''; 144 } 145 //设置新值 146 this.newVal = retStr; 147 return retStr; 148 } 149 150 /** 151 * 添加变量 152 */ 153 addVar(field,values,stack){ 154 let addFlag = false; 155 //判断是否为值表达式 null undefined true false 156 for(let j=0;j<values.length;j++){ 157 if(field === values[j]){ 158 addFlag = true; 159 break; 160 } 161 } 162 addFlag = addFlag || DD.isNumberString(field); 163 //作为字符串处理 164 if(addFlag){ 165 this.addStr(field,stack); 166 }else{ 167 stack.push({ 168 val:field.trim(), 169 type:'field' 170 }); 171 } 172 } 173 174 /** 175 * 添加字符串 176 */ 177 addStr(str,stack){ 178 //如果前一个类型为字符串,则追加到前一个 179 if(stack.length > 0 && stack[stack.length-1].type === "string"){ 180 stack[stack.length-1].val += str; 181 }else{ 182 stack.push({ 183 val:str, 184 type:'string' 185 }); 186 } 187 } 188 189 /** 190 * 提交,旧值换为新值,新值undefined 191 */ 192 commit(){ 193 this.oldVal = this.newVal; 194 this.newVal = undefined; 195 } 196 197 198 /** 199 * 判断是否做了更改 200 */ 201 isChanged(){ 202 return this.oldVal === this.newVal; 203 } 204 205 206}
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

JS - typeof 与 instanceof

一、typeoftypeof操作符返回一个字符串,表示未经计算的操作数的类型使用方法如下:typeof operandtypeof(operand)operand表示对象或原始值的表达式,其类型将被返回举个例子typeof 1 // 'number'typeof '1' // 'string'

JavaScript预解析处理过程原来是这回事

讲解一般来说,Javascript代码的执行包括两个过程:预解析处理过程和逐行解读过程。在代码逐行解读前,Javasript引擎需要进行代码的预处理过程。预解析处理的工作主要是变量提升和给变量分配内存,具体过程是在每个作用域中查找var声明的变量、函数定义和命名函数(函数参数),找到它们后,在当前作用域中给他们分配内存,并给他们设置初始值。预解析设置的初

MYSQL正则表达式

MySQL中使用REGEXP操作符来进行正则表达式匹配。下表中的正则模式可应用于REGEXP操作符中。模式描述^匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配'\\n'或'\\r'之后的位置。$匹配输入字符串的结束位置。如果设置了RegExp对象的Mul

JS 对象数组Array 根据对象object key的值排序sort,很风骚哦

有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak

Python中re(正则表达式)模块学习

今天学习了Python中有关正则表达式的知识。关于正则表达式的语法,不作过多解释,网上有许多学习的资料。这里主要介绍Python中常用的正则表达式处理函数。re.matchre.match尝试从字符串的开始匹配一个模式,如:下面的例子匹配第一个单词。!复制代码(http://static.oschina.net