From 9f7f80b5a8ff60df9e7e9a137703abade0fe69f2 Mon Sep 17 00:00:00 2001 From: Chris O Date: Wed, 17 Dec 2014 09:57:54 -0800 Subject: [PATCH 1/4] Simple non-breaking change to support deep extend. --- src/Angular.js | 18 +++++++++++++++--- test/AngularSpec.js | 12 ++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index 80a9eadb9795..2d61b44dcfb8 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -333,7 +333,7 @@ function setHashKey(obj, h) { * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s) * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`. - * Note: Keep in mind that `angular.extend` does not support recursive merge (deep copy). + * Note: Pass `true` in as the last argument to perform a recursive merge (deep copy). * * @param {Object} dst Destination object. * @param {...Object} src Source object(s). @@ -341,14 +341,26 @@ function setHashKey(obj, h) { */ function extend(dst) { var h = dst.$$hashKey; + var argsLength = arguments.length; + var isDeep = (argsLength >= 3) && (arguments[argsLength - 1] === true); - for (var i = 1, ii = arguments.length; i < ii; i++) { + if (isDeep) { + delete arguments[argsLength - 1]; + } + + for (var i = 1; i < argsLength; i++) { var obj = arguments[i]; if (obj) { var keys = Object.keys(obj); for (var j = 0, jj = keys.length; j < jj; j++) { var key = keys[j]; - dst[key] = obj[key]; + var src = obj[key]; + + if (isDeep) { + src = extend(dst[key], src, true); + } + + dst[key] = src; } } } diff --git a/test/AngularSpec.js b/test/AngularSpec.js index e63789100947..bc2e298b1aec 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -223,6 +223,18 @@ describe('angular', function() { // make sure we retain the old key expect(hashKey(dst)).toEqual(h); }); + + it('should perform deep extend when last argument is true', function() { + var src = { foo: { bar: 'foobar' }}, + dst = { foo: { bazz: 'foobazz' }}; + extend(dst, src, true); + expect(dst).toEqual({ + foo: { + bar: 'foobar', + bazz: 'foobazz' + } + }); + }); }); describe('shallow copy', function() { From c291c5916b97944135fd00b3e1bbb86808ffc260 Mon Sep 17 00:00:00 2001 From: "Chris O." Date: Wed, 17 Dec 2014 15:02:35 -0800 Subject: [PATCH 2/4] Check property is object before deep-extending. --- src/Angular.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Angular.js b/src/Angular.js index 2d61b44dcfb8..72281b259580 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -356,7 +356,7 @@ function extend(dst) { var key = keys[j]; var src = obj[key]; - if (isDeep) { + if (isDeep && isObject(dst[key])) { src = extend(dst[key], src, true); } From d257ae0632477a107f3cc7b8e8b408d797d09bd6 Mon Sep 17 00:00:00 2001 From: "Chris O." Date: Wed, 17 Dec 2014 15:09:59 -0800 Subject: [PATCH 3/4] Updating test to be more thorough. --- test/AngularSpec.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/AngularSpec.js b/test/AngularSpec.js index bc2e298b1aec..9cdf751d6efc 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -225,13 +225,16 @@ describe('angular', function() { }); it('should perform deep extend when last argument is true', function() { - var src = { foo: { bar: 'foobar' }}, + var src = { foo: { bar: 'foobar', age: 10, nothing: null, undef: void 0 }}, dst = { foo: { bazz: 'foobazz' }}; extend(dst, src, true); expect(dst).toEqual({ foo: { bar: 'foobar', - bazz: 'foobazz' + bazz: 'foobazz', + age: 10, + nothing: null, + undef: void 0 } }); }); From e49ed06fd80eea9f1c6ac2206c5f143cd5c64dd2 Mon Sep 17 00:00:00 2001 From: "Chris O." Date: Wed, 17 Dec 2014 15:15:37 -0800 Subject: [PATCH 4/4] Removal of delete per user caitp. --- src/Angular.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index 72281b259580..cd95e8bf2ec0 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -344,9 +344,7 @@ function extend(dst) { var argsLength = arguments.length; var isDeep = (argsLength >= 3) && (arguments[argsLength - 1] === true); - if (isDeep) { - delete arguments[argsLength - 1]; - } + if (isDeep) --argsLength; for (var i = 1; i < argsLength; i++) { var obj = arguments[i];