Bug Tracker

Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#12515 closed bug (invalid)

$.isPlainObject() should return false when obj.constructor === undefined

Reported by: anonymous Owned by: anonymous
Priority: low Milestone: None
Component: core Version: 1.8.0
Keywords: Cc:
Blocked by: Blocking:

Description

An object with an undefined constructor is certainly not a plain object, and if it doesn't have any enumerable properties, then $.extend() with deep=true, erroneously replaces that object with an empty object {} in the target.

(And no, I'm not setting the constructor to undefined. These objects are created externally - hence the un-enumerable properties.)

This could easily be fixed by adding:

...
obj.constructor === undefined ...

to the initial if clause.

Change History (5)

comment:1 Changed 6 years ago by dmethvin

Component: unfiledcore
Milestone: None1.9
Priority: undecidedlow

That's an interesting check and it would seem to be a good one for excluding most host objects. However it doesn't seem to allow a constructor-less object (Object.create(null)) which seems like a bad thing. Technically they aren't run-of-the-mill plain objects but it's useful to employ them as hashes without inherited properties. http://jsfiddle.net/RxVqf/

What type of object was causing this in your code, and in which browsers?

comment:2 in reply to:  1 Changed 6 years ago by anonymous

I work for a company that develops a document management solution which can be used from a native client and/or a web interface. We have developed a framework to allow custom html apps to extend these interfaces. The issue is of course with the IE9 browser embedded in the native client interface and the native c++/COM objects passed to javascript from the main application.

I've had to make other extensions to jQuery for it to play nicely in this environment, which is fine, but when I was extending it to fix this particular issue, it seemed like something that shouldn't happen in general.

I'm not familiar with using constructor-less objects as hashes, but I find it hard to believe that you'd want the $.extend method to turn a hash object into a non-hash object - which it does, as seen here: http://jsfiddle.net/7rvXj/1/

If you really want to allow hash objects to return true, a final test of host-object-i-ness could be added, by simply attempting to add a property to the object in a try block. If it succeeds, remove the property and return true, if it fails, return false.

comment:3 Changed 6 years ago by dmethvin

Owner: set to anonymous
Status: newpending

jQuery utility methods like $.extend were meant to handle jQuery use cases. If you're doing something more ambitious I'd recommend a utility library like lodash.

Are you running into a situation where jQuery is internally using $.extend and failing to do the right thing, for example when processing ajax data? If so, what are you passing to it?

comment:4 Changed 6 years ago by trac-o-bot

Resolution: invalid
Status: pendingclosed

Because we get so many tickets, we often need to return them to the initial reporter for more information. If that person does not reply within 14 days, the ticket will automatically be closed, and that has happened in this case. If you still are interested in pursuing this issue, feel free to add a comment with the requested information and we will be happy to reopen the ticket if it is still valid. Thanks!

comment:5 Changed 6 years ago by dmethvin

Milestone: 1.9None
Note: See TracTickets for help on using tickets.