Skip to content
This repository

Extend recursively #379

Closed
wants to merge 5 commits into from

2 participants

Ben Hall Jeremy Ashkenas
Ben Hall

_.extend handles merges source sub-hash elements with the destination property. Previously it would override the sub-items of the destination property with the source.

Ben Hall

I added support for arrays in commit 83133be but I'm not 100% sure if this is a good idea.

Jeremy Ashkenas
Owner

Yep -- this is extremely unreliable, which is why Underscore doesn't do it. If you'd like to take a look at the kind of thing that would be necessary to do this in a foolproof fashion, check out _.isEqual.

Jeremy Ashkenas jashkenas closed this November 28, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
4  test/objects.js
@@ -39,6 +39,10 @@ $(document).ready(function() {
39 39
     ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
40 40
     result = _.extend({}, {a: void 0, b: null});
41 41
     equals(_.keys(result).join(''), 'b', 'extend does not copy undefined values');
  42
+    same(_.extend({x:'x', a:{b:'c'}}, { a: { d: 'e' } }).a, {b:'c', d:'e'}, 'can extend an object recursively when source property is a hash');
  43
+    same(_.extend({x:'x'}, { a: { b: 'c' } }).a, {b:'c'}, 'can extend an object recursively when destination does not exist');
  44
+    same(_.extend({x:'x', a:[1,2,3]}, { a:[4] }).a, [1,2,3,4], 'can merge arrays');
  45
+    same(_.extend({x:'x', a:{b:'c'}}, { a:[4] }).a, [4], 'overrides destination with source if types are different');
42 46
   });
43 47
 
44 48
   test("objects: defaults", function() {
14  underscore.js
@@ -644,8 +644,18 @@
644 644
   // Extend a given object with all the properties in passed-in object(s).
645 645
   _.extend = function(obj) {
646 646
     each(slice.call(arguments, 1), function(source) {
647  
-      for (var prop in source) {
648  
-        if (source[prop] !== void 0) obj[prop] = source[prop];
  647
+      for (var prop in source) if (!source.hasOwnProperty || source.hasOwnProperty( prop )) {
  648
+        if (source[prop] !== void 0) {
  649
+          if(obj[prop] != undefined && _.isObject(source[prop]) && !_.isArray(source[prop])) {
  650
+            _.extend(obj[prop], source[prop]);
  651
+          }
  652
+          else if(_.isArray(obj[prop]) && _.isArray(source[prop])) {
  653
+            obj[prop] = _.union(obj[prop], source[prop]);
  654
+          }
  655
+          else {
  656
+            obj[prop] = source[prop];
  657
+          }
  658
+        }
649 659
       }
650 660
     });
651 661
     return obj;
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.