Skip to main content

Bug Tracker

Side navigation

#14613 closed bug (notabug)

Opened December 06, 2013 06:55PM UTC

Closed December 06, 2013 07:46PM UTC

Last modified December 06, 2013 09:22PM UTC

Extended objects share single array

Reported by: mwidman@endurancewindpower.com Owned by:
Priority: undecided Milestone: None
Component: core Version: 1.10.2
Keywords: Cc:
Blocked by: Blocking:
Description

I am not sure if this is a bug, a lack of documentation, or a misunderstanding on my part so I apologize in advance.

When using jQuery.extend() to merge 2 objects (obj1, and obj2) into a new empty object (target), any arrays from obj2 are actually shared between instances of target. So if any instance of target modifies the array, all instances see the change.

A code example is worth a thousand words so please check the following jsfiddle: http://jsfiddle.net/WxpSj/1/

I would expect the console output for the array to say just ["cat"] but instead it says ["chicken", "bird", "cat"].

Attachments (0)
Change History (5)

Changed December 06, 2013 07:45PM UTC by gibson042 comment:1

This is expected behavior. Use a deep merge to avoid shallow reference copies: http://jsfiddle.net/WxpSj/3/

http://api.jquery.com/jQuery.extend/:

The merge performed by $.extend() is not recursive by default; if a property of the first object is itself an object or array, it will be completely overwritten by a property with the same key in the second or subsequent object. The values are not merged... However, by passing true for the first function argument, objects will be recursively merged.

Changed December 06, 2013 07:46PM UTC by gibson042 comment:2

component: unfiledcore
resolution: → notabug
status: newclosed

Changed December 06, 2013 07:46PM UTC by gibson042 comment:3

#14614 is a duplicate of this ticket.

Changed December 06, 2013 09:15PM UTC by anonymous comment:4

Yes, I read that documentation but it does really talk about this case. It is saying (at least how I read it based on the provided example) that if you merge 2 objects both containing an array with the same name, the second one will clobber the first rather than merging it's elements with the first object's array.

The fact that "if you do not do a deep merge, the array is actually a reference and all modifications of that array's elements will be present in any other object that extends from this one" is not mentioned or implied anywhere that I can see.

So then maybe this requires documentation updates (which I believe requires another bug request)?

Changed December 06, 2013 09:22PM UTC by dmethvin comment:5

All assignments of objects in JavaScript use the same referenced object rather than creating a new independent copy. This seems like a misunderstanding of JavaScript arrays rather than a jQuery question. If the documentation was truly ambiguous we would have heard more about it in the past 7 years.