這次我們來(lái)看一下angular的Sandboxing Angular Expressions。關(guān)于內(nèi)置方法的,核心有兩塊:Lexer和Parser。其中大家對(duì)$parse可能更了解一點(diǎn)。好了不多廢話,先看Lexer的內(nèi)部結(jié)構(gòu):
1.Lexer
//構(gòu)造函數(shù)var Lexer = function(options) { this.options = options;};//原型 Lexer.prototype = { constructor: Lexer, lex: function(){}, is: function(){}, peek: function(){ /* 返回表達(dá)式的下一個(gè)位置的數(shù)據(jù),如果沒(méi)有則返回false */ }, isNumber: function(){ /* 判斷當(dāng)前表達(dá)式是否是一個(gè)數(shù)字 */ }, isWhitespace: function(){/* 判斷當(dāng)前表達(dá)式是否是空格符 */}, isIdent: function(){/* 判斷當(dāng)前表達(dá)式是否是英文字符(包含_和$) */}, isExpOperator: function(){/* 判斷當(dāng)時(shí)表達(dá)式是否是-,+還是數(shù)字 */}, throwError: function(){ /* 拋出異常 */}, readNumber: function(){ /* 讀取數(shù)字 */}, readIdent: function(){ /* 讀取字符 */}, readString: function(){ /*讀取攜帶''或""的字符串*/ }};這里指出一點(diǎn),因?yàn)槭潜磉_(dá)式。所以類(lèi)似"123"這類(lèi)的東西,在Lexer看來(lái)應(yīng)該算是數(shù)字而非字符串。表達(dá)式中的字符串必須使用單引號(hào)或者雙引號(hào)來(lái)標(biāo)識(shí)。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())) { /* 嘗試判斷是否是數(shù)字 */ 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 { /* 嘗試匹配操作運(yùn)算 */ 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; }主要看一下匹配操作運(yùn)算。這里源碼中會(huì)調(diào)用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});
新聞熱點(diǎn)
疑難解答
圖片精選