diff --git a/src/ng/compile.js b/src/ng/compile.js index 2e252a8a62df..cfa27c928f23 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -929,7 +929,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { */ $observe: function(key, fn) { var attrs = this, - $$observers = (attrs.$$observers || (attrs.$$observers = {})), + $$observers = (attrs.$$observers || (attrs.$$observers = Object.create(null))), listeners = ($$observers[key] || ($$observers[key] = [])); listeners.push(fn); diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index cc0203e104b8..cda31ed4c1f3 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -3124,6 +3124,34 @@ describe('$compile', function() { })); + it('should be able to bind attribute names which are present in Object.prototype', function() { + module(function() { + directive('inProtoAttr', valueFn({ + scope: { + 'constructor': '@', + // Spidermonkey extension, may be obsolete in the future + 'watch': '=', + 'unwatch': '&' + } + })); + }); + inject(function($rootScope) { + expect(function() { + compile('
'); + }).not.toThrow(); + var isolateScope = element.isolateScope(); + + expect(typeof isolateScope.constructor).toBe('string'); + expect(isArray(isolateScope.watch)).toBe(true); + expect(typeof isolateScope.unwatch).toBe('function'); + expect($rootScope.value).toBeUndefined(); + isolateScope.unwatch(); + expect($rootScope.value).toBe(true); + }); + }); + + describe('bind-once', function () { function countWatches(scope) {