matthewkastor / object-merge

Merges JavaScript objects recursively without altering the objects merged.
16 stars 9 forks source link

new 'arraysAsPrimitives' option to allow specifying to overwrite arrays not merge them #6

Open arieljake opened 9 years ago

arieljake commented 9 years ago

requires throwOnCircularRef option to be set to false

matthewkastor commented 9 years ago

What should it do when taking an array and merging an object into it? Given two objects with a property named arr where the first is an array and the second is an object with properties (which may be named by numbers) What would the expected behavior be?

var objA = {
    arr : [1,2,3,4,5]
};
var objB = {
    arr : {'9' : 9, '8' : 8, '7' : 7, '6' : 6}
};

What would happen when the first object is an object and the second is an array? Would the array clobber the object?

The throw on circular reference guard prevents users from sending this thing on an infinite walk. It works by keeping a log of all the objects it's seen and throwing an error if the same object is encountered twice. You could still check for circular references if you short circuit the check when comparing arrays and this option is on.

Does this still traverse arrays and merge their elements together when they're not scalar values? Given the situation where an object and an array are merged together, would property 1 still be merged into index 1, or would the array clobber the object altogether?

I don't know, the more I think about it, the more this sounds like a kind of broken, shallow clone function. object-merge is built on top of another module I've developed called object-walk that might be better suited for what you're trying to do. https://github.com/matthewkastor/object-walk With object-walk you can do both breadth first and depth first traversal at the same time. By using object-walk with a "descention function" you're doing breadth first traversal, by specifying an "ascention function" you're doing a depth first traversal. The point of both is that you'll gain access to all the nodes on the way down, then begin at the leaves to work your way back up, exercising some kind of transformation or filtering function at every step.

http://en.wikipedia.org/wiki/Breadth-first_search http://en.wikipedia.org/wiki/Depth-first_search

With the object-walk you could do any kind of customized merge or shallow clone you'd want to do. This object-merge will do all kinds of crazy stuff, like try to take the string value of encountered functions, run them through eval, and create a completely new function. The whole idea was to break any references to the original objects while creating mixins. Taking arrays as primitives would leave the original and the output of the merge linked together, so that changing the array in the merged output would be reflected in the original array. I'd have to do something like walking the array and breaking references the whole way down, before taking it as a primitive, since any objects held in the array would also be bound to their original counterparts.

I do appreciate your efforts. Merging this in the way it is would leave too may open questions about behavior and scope for me to sleep at night. Give me an idea of what you really want to do and I'll see if it can make sense here, or in a different dedicated module. I mean it, be really specific, I love puzzles. XD