diff options
| author | Misko Hevery | 2010-05-30 19:42:21 -0700 |
|---|---|---|
| committer | Misko Hevery | 2010-05-30 19:42:21 -0700 |
| commit | 2e33e89a77d115ff17f5841ec328b1c1e4228161 (patch) | |
| tree | 22a97d5c70f2e74ffb4dfe789c82545363abed55 /src | |
| parent | 1aa99c08e9ccd515a333478f00b361f40c622002 (diff) | |
| download | angular.js-2e33e89a77d115ff17f5841ec328b1c1e4228161.tar.bz2 | |
added compiled getterFN for better performance
Diffstat (limited to 'src')
| -rw-r--r-- | src/Parser.js | 7 | ||||
| -rw-r--r-- | src/Scope.js | 35 |
2 files changed, 38 insertions, 4 deletions
diff --git a/src/Parser.js b/src/Parser.js index cfb72c72..df270792 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -151,9 +151,7 @@ Lexer.prototype = { } var fn = Lexer.OPERATORS[ident]; if (!fn) { - fn = function(self){ - return getter(self, ident); - }; + fn = getterFn(ident); fn.isAssignable = ident; } this.tokens.push({index:start, text:ident, fn:fn}); @@ -563,8 +561,9 @@ Parser.prototype = { fieldAccess: function(object) { var field = this.expect().text; + var getter = getterFn(field); var fn = function (self){ - return getter(object(self), field); + return getter(object(self)); }; fn.isAssignable = field; return fn; diff --git a/src/Scope.js b/src/Scope.js index bed0ff6d..1c223130 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -43,6 +43,41 @@ function setter(instance, path, value){ return value; } +/////////////////////////////////// + +var getterFnCache = {}; +function getterFn(path){ + var fn = getterFnCache[path]; + if (fn) return fn; + + var code = 'function (self){\n'; + code += ' var last, fn, type;\n'; + foreach(path.split('.'), function(key) { + code += ' if(!self) return self;\n'; + code += ' last = self;\n'; + code += ' self = self.' + key + ';\n'; + code += ' if(typeof self == "function") \n'; + code += ' self = function(){ return last.'+key+'.apply(last, arguments); };\n'; + if (key.charAt(0) == '$') { + // special code for super-imposed functions + var name = key.substr(1); + code += ' if(!self) {\n'; + code += ' type = angular.Global.typeOf(last);\n'; + code += ' fn = (angular[type.charAt(0).toUpperCase() + type.substring(1)]||{})["' + name + '"];\n'; + code += ' if (fn)\n'; + code += ' self = function(){ return fn.apply(last, [last].concat(slice.call(arguments, 0, arguments.length))); };\n'; + code += ' }\n'; + } + }); + code += ' return self;\n}'; + fn = eval('(' + code + ')'); + fn.toString = function(){ return code; }; + + return getterFnCache[path] = fn; +} + +/////////////////////////////////// + var compileCache = {}; function expressionCompile(exp){ if (isFunction(exp)) return exp; |
