首页 > 语言 > JavaScript > 正文

Angularjs 1.3 中的$parse实例代码

2024-05-06 15:26:44
字体:
来源:转载
供稿:网友

这次我们来看一下angular的Sandboxing Angular Expressions。关于内置方法的,核心有两块:Lexer和Parser。其中大家对$parse可能更了解一点。好了不多废话,先看Lexer的内部结构:

1.Lexer

//构造函数var Lexer = function(options) { this.options = options;};//原型 Lexer.prototype = { constructor: Lexer, lex: function(){}, is: function(){}, peek: function(){ /* 返回表达式的下一个位置的数据,如果没有则返回false */ }, isNumber: function(){ /* 判断当前表达式是否是一个数字 */ }, isWhitespace: function(){/* 判断当前表达式是否是空格符 */}, isIdent: function(){/* 判断当前表达式是否是英文字符(包含_和$) */}, isExpOperator: function(){/* 判断当时表达式是否是-,+还是数字 */}, throwError: function(){ /* 抛出异常 */}, readNumber: function(){ /* 读取数字 */}, readIdent: function(){ /* 读取字符 */}, readString: function(){ /*读取携带''或""的字符串*/ }};

 这里指出一点,因为是表达式。所以类似"123"这类的东西,在Lexer看来应该算是数字而非字符串。表达式中的字符串必须使用单引号或者双引号来标识。Lexer的核心逻辑在lex方法中:

lex: function(text) { this.text = text; this.index = 0; this.tokens = []; while (this.index < this.text.length) {  var ch = this.text.charAt(this.index);  if (ch === '"' || ch === "'") {  /* 尝试判断是否是字符串 */  this.readString(ch);  } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {  /* 尝试判断是否是数字 */  this.readNumber();  } else if (this.isIdent(ch)) {  /* 尝试判断是否是字母 */  this.readIdent();  } else if (this.is(ch, '(){}[].,;:?')) {  /* 判断是否是(){}[].,;:? */  this.tokens.push({index: this.index, text: ch});  this.index++;  } else if (this.isWhitespace(ch)) {  /* 判断是否是空白符 */  this.index++;  } else {  /* 尝试匹配操作运算 */  var ch2 = ch + this.peek();  var ch3 = ch2 + this.peek(2);  var op1 = OPERATORS[ch];  var op2 = OPERATORS[ch2];  var op3 = OPERATORS[ch3];  if (op1 || op2 || op3) {   var token = op3 ? ch3 : (op2 ? ch2 : ch);   this.tokens.push({index: this.index, text: token, operator: true});   this.index += token.length;  } else {   this.throwError('Unexpected next character ', this.index, this.index + 1);  }  } } return this.tokens; }

主要看一下匹配操作运算。这里源码中会调用OPERATORS。看一下OPERATORS:

var OPERATORS = extend(createMap(), { '+':function(self, locals, a, b) {  a=a(self, locals); b=b(self, locals);  if (isDefined(a)) {  if (isDefined(b)) {   return a + b;  }  return a;  }  return isDefined(b) ? b : undefined;}, '-':function(self, locals, a, b) {   a=a(self, locals); b=b(self, locals);   return (isDefined(a) ? a : 0) - (isDefined(b) ? b : 0);  }, '*':function(self, locals, a, b) {return a(self, locals) * b(self, locals);}, '/':function(self, locals, a, b) {return a(self, locals) / b(self, locals);}, '%':function(self, locals, a, b) {return a(self, locals) % b(self, locals);}, '===':function(self, locals, a, b) {return a(self, locals) === b(self, locals);}, '!==':function(self, locals, a, b) {return a(self, locals) !== b(self, locals);}, '==':function(self, locals, a, b) {return a(self, locals) == b(self, locals);}, '!=':function(self, locals, a, b) {return a(self, locals) != b(self, locals);}, '<':function(self, locals, a, b) {return a(self, locals) < b(self, locals);}, '>':function(self, locals, a, b) {return a(self, locals) > b(self, locals);}, '<=':function(self, locals, a, b) {return a(self, locals) <= b(self, locals);}, '>=':function(self, locals, a, b) {return a(self, locals) >= b(self, locals);}, '&&':function(self, locals, a, b) {return a(self, locals) && b(self, locals);}, '||':function(self, locals, a, b) {return a(self, locals) || b(self, locals);}, '!':function(self, locals, a) {return !a(self, locals);}, //Tokenized as operators but parsed as assignment/filters '=':true, '|':true});            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选