Bug Tracker

Opened 8 years ago

Closed 7 years ago

#11185 closed bug (patchwelcome)

isPlainObject gives wrong result in IE6/7/8 when constructor adds properties

Reported by: pcl Owned by:
Priority: low Milestone: 1.next
Component: core Version: 1.7.1
Keywords: Cc:
Blocked by: Blocking:

Description

Test = function() { this.a = 1; }
    
alert($.isPlainObject(new Test()); // false in all browsers

Test.prototype = { b: 1 };

alert($.isPlainObject(new Test()); // true in IE6/7/8

"Own properties are enumerated firstly" is apparently not the case in these versions of IE, so the property added in the constructor gets tested instead of a prototype property.

A workaround is to do this instead:

Test.prototype = $.extend(Test.prototype, {b: 1});

Which ensures this earlier check passes:

!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")

http://jsfiddle.net/CHwpg/2/

Change History (6)

comment:1 Changed 8 years ago by dmethvin

Resolution: invalid
Status: newclosed

If it's created via a constructor function, it's not really a plain object. The documentation says this:

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

Check to see if an object is a plain object (created using "{}" or "new Object").

comment:2 in reply to:  1 Changed 8 years ago by pcl

Replying to dmethvin:

If it's created via a constructor function, it's not really a plain object.

Yes, the bug is that isPlainObject is returning true for what is not a plain object.

comment:3 Changed 8 years ago by dmethvin

Resolution: invalid
Status: closedreopened

Oh hah! I read it backwards. Disregard, I suck ....

comment:4 Changed 8 years ago by dmethvin

Component: unfiledcore
Milestone: None1.8
Status: reopenedopen

Not sure this needs fixing, our use cases for isPlainObject don't require this level of differentiation. If it's easily fixable though, sure.

comment:5 Changed 8 years ago by dmethvin

Milestone: 1.81.next
Priority: undecidedlow

comment:6 Changed 7 years ago by dmethvin

Resolution: patchwelcome
Status: openclosed

Since this method is intended primarily for our internal use, it doesn't seem like it's worth fixing because it works for our needs. As an example, $.extend uses it, but we already know that constructed objects are impossible to handle there.

If there are some specific critical situations where this fails, or you have a simple fix, let us know.

Note: See TracTickets for help on using tickets.