diff --git a/src/ng/compile.js b/src/ng/compile.js index ae5b3cf9e2d3..b1d4185f6d23 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -2576,7 +2576,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { break; case '&': + // Don't assign Object.prototype method to scope + if (!attrs.hasOwnProperty(attrName) && optional) break; + parentGet = $parse(attrs[attrName]); + + // Don't assign noop to destination if expression is not valid + if (parentGet === noop && optional) break; + destination[scopeName] = function(locals) { return parentGet(scope, locals); }; diff --git a/src/ng/parse.js b/src/ng/parse.js index a4dcac8c2e3b..beb8e562791a 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -1079,7 +1079,7 @@ function $ParseProvider() { return addInterceptor(exp, interceptorFn); default: - return addInterceptor(noop, interceptorFn); + return noop; } }; diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 304e4652d5a6..baf2a5d6f469 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -3084,7 +3084,9 @@ describe('$compile', function() { colref: '=*', colrefAlias: '=* colref', expr: '&', - exprAlias: '&expr' + optExpr: '&?', + exprAlias: '&expr', + constructor: '&?' }, link: function(scope) { componentScope = scope; @@ -3224,6 +3226,38 @@ describe('$compile', function() { }); + it('should not initialize scope value if optional expression binding is not passed', inject(function($compile) { + compile('
'); + var isolateScope = element.isolateScope(); + expect(isolateScope.optExpr).toBeUndefined(); + })); + + + it('should not initialize scope value if optional expression binding with Object.prototype name is not passed', inject(function($compile) { + compile('
'); + var isolateScope = element.isolateScope(); + expect(isolateScope.constructor).toBe($rootScope.constructor); + })); + + + it('should initialize scope value if optional expression binding is passed', inject(function($compile) { + compile('
'); + var isolateScope = element.isolateScope(); + expect(typeof isolateScope.optExpr).toBe('function'); + expect(isolateScope.optExpr()).toBe('did!'); + expect($rootScope.value).toBe('did!'); + })); + + + it('should initialize scope value if optional expression binding with Object.prototype name is passed', inject(function($compile) { + compile('
'); + var isolateScope = element.isolateScope(); + expect(typeof isolateScope.constructor).toBe('function'); + expect(isolateScope.constructor()).toBe('did!'); + expect($rootScope.value).toBe('did!'); + })); + + describe('bind-once', function() { function countWatches(scope) {