@@ -891,19 +891,19 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
891891 ? function cspSafeGetter ( scope , locals ) {
892892 var pathVal = ( locals && locals . hasOwnProperty ( key0 ) ) ? locals : scope ;
893893
894- if ( pathVal === null || pathVal === undefined ) return pathVal ;
894+ if ( pathVal == null ) return pathVal ;
895895 pathVal = pathVal [ key0 ] ;
896896
897- if ( ! key1 || pathVal === null || pathVal === undefined ) return pathVal ;
897+ if ( ! key1 || pathVal == null ) return pathVal ;
898898 pathVal = pathVal [ key1 ] ;
899899
900- if ( ! key2 || pathVal === null || pathVal === undefined ) return pathVal ;
900+ if ( ! key2 || pathVal == null ) return pathVal ;
901901 pathVal = pathVal [ key2 ] ;
902902
903- if ( ! key3 || pathVal === null || pathVal === undefined ) return pathVal ;
903+ if ( ! key3 || pathVal == null ) return pathVal ;
904904 pathVal = pathVal [ key3 ] ;
905905
906- if ( ! key4 || pathVal === null || pathVal === undefined ) return pathVal ;
906+ if ( ! key4 || pathVal == null ) return pathVal ;
907907 pathVal = pathVal [ key4 ] ;
908908
909909 return pathVal ;
@@ -912,7 +912,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
912912 var pathVal = ( locals && locals . hasOwnProperty ( key0 ) ) ? locals : scope ,
913913 promise ;
914914
915- if ( pathVal === null || pathVal === undefined ) return pathVal ;
915+ if ( pathVal == null ) return pathVal ;
916916
917917 pathVal = pathVal [ key0 ] ;
918918 if ( pathVal && pathVal . then ) {
@@ -924,7 +924,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
924924 }
925925 pathVal = pathVal . $$v ;
926926 }
927- if ( ! key1 || pathVal === null || pathVal === undefined ) return pathVal ;
927+ if ( ! key1 || pathVal == null ) return pathVal ;
928928
929929 pathVal = pathVal [ key1 ] ;
930930 if ( pathVal && pathVal . then ) {
@@ -936,7 +936,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
936936 }
937937 pathVal = pathVal . $$v ;
938938 }
939- if ( ! key2 || pathVal === null || pathVal === undefined ) return pathVal ;
939+ if ( ! key2 || pathVal == null ) return pathVal ;
940940
941941 pathVal = pathVal [ key2 ] ;
942942 if ( pathVal && pathVal . then ) {
@@ -948,7 +948,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
948948 }
949949 pathVal = pathVal . $$v ;
950950 }
951- if ( ! key3 || pathVal === null || pathVal === undefined ) return pathVal ;
951+ if ( ! key3 || pathVal == null ) return pathVal ;
952952
953953 pathVal = pathVal [ key3 ] ;
954954 if ( pathVal && pathVal . then ) {
@@ -960,7 +960,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
960960 }
961961 pathVal = pathVal . $$v ;
962962 }
963- if ( ! key4 || pathVal === null || pathVal === undefined ) return pathVal ;
963+ if ( ! key4 || pathVal == null ) return pathVal ;
964964
965965 pathVal = pathVal [ key4 ] ;
966966 if ( pathVal && pathVal . then ) {
@@ -976,6 +976,27 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
976976 } ;
977977}
978978
979+ function simpleGetterFn1 ( key0 , fullExp ) {
980+ ensureSafeMemberName ( key0 , fullExp ) ;
981+
982+ return function simpleGetterFn1 ( scope , locals ) {
983+ if ( scope == null ) return scope ;
984+ return ( ( locals && locals . hasOwnProperty ( key0 ) ) ? locals : scope ) [ key0 ] ;
985+ } ;
986+ }
987+
988+ function simpleGetterFn2 ( key0 , key1 , fullExp ) {
989+ ensureSafeMemberName ( key0 , fullExp ) ;
990+ ensureSafeMemberName ( key1 , fullExp ) ;
991+
992+ return function simpleGetterFn2 ( scope , locals ) {
993+ if ( scope == null ) return scope ;
994+ scope = ( ( locals && locals . hasOwnProperty ( key0 ) ) ? locals : scope ) [ key0 ] ;
995+
996+ return scope == null ? scope : scope [ key1 ] ;
997+ } ;
998+ }
999+
9791000function getterFn ( path , options , fullExp ) {
9801001 // Check whether the cache has this getter already.
9811002 // We can use hasOwnProperty directly on the cache because we ensure,
@@ -988,7 +1009,13 @@ function getterFn(path, options, fullExp) {
9881009 pathKeysLength = pathKeys . length ,
9891010 fn ;
9901011
991- if ( options . csp ) {
1012+ // When we have only 1 or 2 tokens, use optimized special case closures.
1013+ // http://jsperf.com/angularjs-parse-getter/6
1014+ if ( ! options . unwrapPromises && pathKeysLength === 1 ) {
1015+ fn = simpleGetterFn1 ( pathKeys [ 0 ] , fullExp ) ;
1016+ } else if ( ! options . unwrapPromises && pathKeysLength === 2 ) {
1017+ fn = simpleGetterFn2 ( pathKeys [ 0 ] , pathKeys [ 1 ] , fullExp ) ;
1018+ } else if ( options . csp ) {
9921019 if ( pathKeysLength < 6 ) {
9931020 fn = cspSafeGetterFn ( pathKeys [ 0 ] , pathKeys [ 1 ] , pathKeys [ 2 ] , pathKeys [ 3 ] , pathKeys [ 4 ] , fullExp ,
9941021 options ) ;
@@ -1006,11 +1033,10 @@ function getterFn(path, options, fullExp) {
10061033 } ;
10071034 }
10081035 } else {
1009- var code = 'var l, fn, p;\n' ;
1036+ var code = 'var p;\n' ;
10101037 forEach ( pathKeys , function ( key , index ) {
10111038 ensureSafeMemberName ( key , fullExp ) ;
1012- code += 'if(s === null || s === undefined) return s;\n' +
1013- 'l=s;\n' +
1039+ code += 'if(s == null) return s;\n' +
10141040 's=' + ( index
10151041 // we simply dereference 's' on any .dot notation
10161042 ? 's'
@@ -1033,10 +1059,10 @@ function getterFn(path, options, fullExp) {
10331059 /* jshint -W054 */
10341060 var evaledFnGetter = new Function ( 's' , 'k' , 'pw' , code ) ; // s=scope, k=locals, pw=promiseWarning
10351061 /* jshint +W054 */
1036- evaledFnGetter . toString = function ( ) { return code ; } ;
1037- fn = function ( scope , locals ) {
1062+ evaledFnGetter . toString = valueFn ( code ) ;
1063+ fn = options . unwrapPromises ? function ( scope , locals ) {
10381064 return evaledFnGetter ( scope , locals , promiseWarning ) ;
1039- } ;
1065+ } : evaledFnGetter ;
10401066 }
10411067
10421068 // Only cache the value if it's not going to mess up the cache object
0 commit comments