Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix(angular): do not copy $$hashKey in copy/extend functions. #2423

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -228,13 +243,16 @@ 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){
dst[key] = value;
});
}
});

setHashKey(dst,h);
return dst;
}

Expand Down Expand Up @@ -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;
Expand Down
57 changes: 57 additions & 0 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down