Bug Tracker

Opened 7 years ago

Closed 7 years ago

Last modified 6 years ago

#10458 closed bug (wontfix)

jQuery.isPlainObject() always returns false when Object.prototype has a properties

Reported by: vovan-ve@… Owned by:
Priority: low Milestone: None
Component: core Version: 1.6.4
Keywords: Cc:
Blocked by: Blocking:

Description

jQuery.isPlainObject() finally enumerates all propertyes of an object. If the last property is own, then function relies that it is an Object. As the result, it is not allowed to have any properties in prototype. So, if we extend Object.prototype with at least one property, jQuery.isPlainObject() will always return false for new objects, created after.

jsFiddle: http://jsfiddle.net/kqe95/

alert(jQuery.isPlainObject({})); // true
Object.prototype.foo = function(){};
alert(jQuery.isPlainObject({})); // false

Change History (10)

comment:1 Changed 7 years ago by Rick Waldron

Component: unfiledcore
Priority: undecidedlow
Resolution: wontfix
Status: newclosed

comment:2 Changed 6 years ago by laurentiu.macovei@…

This is still not fixed! Besides the function does a lot of "stuff" and its performance is very low! It is extensively used by $.extend when creating deep copies!

Why not simply comparing either object.proto == Object.prototype or in IE Object.getPrototypeOf(object) == Object.prototype

if Object.getPrototypeOf is missing as well, the current implementation could be good enough

Tests are here: http://jsfiddle.net/LLKET/1/

comment:3 Changed 6 years ago by Rick Waldron

Right... it's not fixed because I closed it as "won't fix", because jQuery won't fix bugs that are caused by user code that does stupid things like extending Object.prototype

comment:4 in reply to:  3 ; Changed 6 years ago by vovan-ve

Replying to rwaldron:

... user code that does stupid things like extending Object.prototype

I still think, that You are not right. Can you give a prooflink to confirm this words?

comment:5 Changed 6 years ago by laurentiu.macovei@…

Why my above approach is not a good fix for all modern browsers?

comment:6 in reply to:  5 Changed 6 years ago by vovan-ve

Replying to laurentiu.macovei@…:

Why my above approach is not a good fix for all modern browsers?

  1. http://jsfiddle.net/FdSwc/
    function Foo() {};
    Foo.prototype = Object.prototype;
    alert( new Foo().__proto__ === Object.prototype );
    
  2. one_window.Object !== another_window.Object;
    /* this is window A */
    window.FooBar = {};
    open('<url to run next code in B>');
    
    /* this is window B opened by window.open() in A */
    alert( opener.Object === Object ); // false
    alert( opener.FooBar.__proto__ === Object.prototype ); // false
    alert( opener.FooBar.__proto__ === opener.Object.prototype ); // true
    

comment:7 Changed 6 years ago by laurentiu.macovei@…

That's correct but I think you really don't care about that. It may be useful in 0.001% of cases, whereas you could use the current option.

comment:8 in reply to:  4 ; Changed 6 years ago by Rick Waldron

Replying to vovan-ve:

Replying to rwaldron:

... user code that does stupid things like extending Object.prototype

I still think, that You are not right. Can you give a prooflink to confirm this words?

jQuery's Won't Fix: http://contribute.jquery.org/wont-fix/

The problem with adding properties to Object.prototype is that all Object's will then inherit those properties, whether they want to or not—and these properties will appear in for-in loops.

Since ES5, Object.prototype can be safely augmented with Object.definePropert(y|ies) by creating a properties and specifying that its enumerable? field is false.

comment:9 in reply to:  8 Changed 6 years ago by anonymous

Replying to rwaldron:

Replying to vovan-ve:

...

Thanks for the links. Now I see I'm not right.

comment:10 Changed 6 years ago by DotNetWise

Even so, jQuery will simply fail when Object.prototype will have something added. But that can be sorted out with ES5 Object.defineProperty("someProperty", { enumerable: false});

Note: See TracTickets for help on using tickets.