diff --git a/src/Angular.js b/src/Angular.js index bf64c6c27de5..45023d6c64d6 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -215,6 +215,21 @@ function nextUid() { return uid.join(''); } + +/** + * Set or clear the hashkey for an object. + * @param obj object + * @param h the hashkey (!truthy to delete the hashkey) + */ +function setHashKey(obj, h) { + if (h) { + obj.$$hashKey = h; + } + else { + delete obj.$$hashKey; + } +} + /** * @ngdoc function * @name angular.extend @@ -228,6 +243,7 @@ function nextUid() { * @param {...Object} src Source object(s). */ function extend(dst) { + var h = dst.$$hashKey; forEach(arguments, function(obj){ if (obj !== dst) { forEach(obj, function(value, key){ @@ -235,6 +251,8 @@ function extend(dst) { }); } }); + + setHashKey(dst,h); return dst; } @@ -594,12 +612,14 @@ function copy(source, destination){ destination.push(copy(source[i])); } } else { + var h = destination.$$hashKey; forEach(destination, function(value, key){ delete destination[key]; }); for ( var key in source) { destination[key] = copy(source[key]); } + setHashKey(destination,h); } } return destination; diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 7f1ab8a32c26..0e5017ad25d9 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -98,6 +98,63 @@ describe('angular', function() { src = dst = [2, 4]; expect(function() { copy(src, dst); }).toThrow("Can't copy equivalent objects or arrays"); }); + + it('should not copy the private $$hashKey', function() { + var src,dst; + src = {}; + hashKey(src); + dst = copy(src); + expect(hashKey(dst)).not.toEqual(hashKey(src)); + }); + + it('should retain the previous $$hashKey', function() { + var src,dst,h; + src = {}; + dst = {}; + // force creation of a hashkey + h = hashKey(dst); + hashKey(src); + dst = copy(src,dst); + + // make sure we don't copy the key + expect(hashKey(dst)).not.toEqual(hashKey(src)); + // make sure we retain the old key + expect(hashKey(dst)).toEqual(h); + }); + }); + + describe("extend", function() { + + it('should not copy the private $$hashKey', function() { + var src,dst; + src = {}; + dst = {}; + hashKey(src); + dst = extend(dst,src); + expect(hashKey(dst)).not.toEqual(hashKey(src)); + }); + + it('should retain the previous $$hashKey', function() { + var src,dst,h; + src = {}; + dst = {}; + h = hashKey(dst); + hashKey(src); + dst = extend(dst,src); + // make sure we don't copy the key + expect(hashKey(dst)).not.toEqual(hashKey(src)); + // make sure we retain the old key + expect(hashKey(dst)).toEqual(h); + }); + + it('should work when extending with itself', function() { + var src,dst,h; + dst = src = {}; + h = hashKey(dst); + dst = extend(dst,src); + // make sure we retain the old key + expect(hashKey(dst)).toEqual(h); + }); }); describe('shallow copy', function() {