From fe103f013c4c7684a5d6af5eb6525d8b0d06471d Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Sat, 13 Sep 2014 11:51:30 -0700 Subject: [PATCH] refactor($parse): change 'this' to a $parse keyword instead of scope field BREAKING CHANGE: - $scope['this'] no longer exits on the $scope object - $parse-ed expressions no longer allow chaining 'this' such as this['this'] or $parent['this'] - 'this' in $parse-ed expressions can no longer be overriden, if a variable named 'this' is put on the scope it must be accessed using this['this'] --- src/ng/parse.js | 5 +++++ src/ng/rootScope.js | 3 +-- test/ng/rootScopeSpec.js | 21 +++++++++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/ng/parse.js b/src/ng/parse.js index d09cc516a0db..8b7195ccd0c3 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -92,6 +92,11 @@ forEach({ CONSTANTS[name] = constantGetter; }); +//Not quite a constant, but can be lex/parsed the same +CONSTANTS['this'] = function(self) { return self; }; +CONSTANTS['this'].sharedGetter = true; + + //Operators - will be wrapped by binaryFn/unaryFn/assignment/filter var OPERATORS = extend(createMap(), { /* jshint bitwise : false */ diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index 77cba19968ab..807be109f678 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -128,7 +128,7 @@ function $RootScopeProvider(){ this.$$phase = this.$parent = this.$$watchers = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = null; - this['this'] = this.$root = this; + this.$root = this; this.$$destroyed = false; this.$$asyncQueue = []; this.$$postDigestQueue = []; @@ -212,7 +212,6 @@ function $RootScopeProvider(){ } child = new this.$$ChildScope(); } - child['this'] = child; child.$parent = this; child.$$prevSibling = this.$$childTail; if (this.$$childHead) { diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js index e3168ec10e86..a0d1641dae21 100644 --- a/test/ng/rootScopeSpec.js +++ b/test/ng/rootScopeSpec.js @@ -51,8 +51,25 @@ describe('Scope', function() { describe('this', function() { - it('should have a \'this\'', inject(function($rootScope) { - expect($rootScope['this']).toEqual($rootScope); + it('should evaluate \'this\' to be the scope', inject(function($rootScope) { + var child = $rootScope.$new(); + expect($rootScope.$eval('this')).toEqual($rootScope); + expect(child.$eval('this')).toEqual(child); + })); + + it('\'this\' should not be recursive', inject(function($rootScope) { + expect($rootScope.$eval('this.this')).toBeUndefined(); + expect($rootScope.$eval('$parent.this')).toBeUndefined(); + })); + + it('should not be able to overwrite the \'this\' keyword', inject(function($rootScope) { + $rootScope['this'] = 123; + expect($rootScope.$eval('this')).toEqual($rootScope); + })); + + it('should be able to access a variable named \'this\'', inject(function($rootScope) { + $rootScope['this'] = 42; + expect($rootScope.$eval('this[\'this\']')).toBe(42); })); });