Skip to content

Commit

Permalink
Fixes #13571. jQuery.isPlainObject 1.9.x compatibility
Browse files Browse the repository at this point in the history
Signed-off-by: Rick Waldron <waldron.rick@gmail.com>
  • Loading branch information
rwaldron committed Mar 6, 2013
1 parent 49abe3d commit 8d1c422
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
11 changes: 8 additions & 3 deletions src/core.js
Expand Up @@ -422,8 +422,11 @@ jQuery.extend({
},

isPlainObject: function( obj ) {
var key;
// Not plain objects:
// - Any object or value whose internal [[Class]] property is not "[object Object]"
// ...Unless it was a constructor, whose prototype property was paved over by
// by a plain object at its declaration. #13571
// - DOM nodes
// - window
if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
Expand All @@ -442,9 +445,11 @@ jQuery.extend({
return false;
}

// If the function hasn't returned already, we're confident that
// |obj| is a plain object, created by {} or constructed with new Object
return true;
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
for ( key in obj ) {}

return key === undefined || core_hasOwn.call( obj, key );
},

isEmptyObject: function( obj ) {
Expand Down
43 changes: 41 additions & 2 deletions test/unit/core.js
Expand Up @@ -296,9 +296,9 @@ test("type", function() {
});

asyncTest("isPlainObject", function() {
expect(15);
expect(16);

var pass, iframe, doc,
var pass, iframe, doc, c, extended,
fn = function() {};

// The use case that we want to match
Expand Down Expand Up @@ -360,6 +360,45 @@ asyncTest("isPlainObject", function() {
} catch(e) {
window.iframeDone( Object, "iframes not supported" );
}

// #13571
function C() {}
C.prototype = {
x: 1
};
c = new C();

extended = jQuery.extend( true, {}, {
target: c
});

strictEqual(
extended.target, c,
"Instances, whose constructor defined its prototype by assigning a plain object, " +
"will lie about their true identity to preserve a broken user-code expectation"
);
//
// The test above is broken and tests a broken feature, to support a misinformed
// assumption, as documented here:
//
// http://bugs.jquery.com/ticket/13571#comment:4
//
// It will not pass if the object being assigned as the prototype
// has no properties:
//
// function C() {}
// C.prototype = {};
// c = new C();

// extended = jQuery.extend( true, {}, {
// target: c
// });

// strictEqual( extended.target, c, "Undetectable, will fail every time" );
//
// The solution is to reset the constructor property of your plain object prototypes.
//
//
});

test("isFunction", function() {
Expand Down

0 comments on commit 8d1c422

Please sign in to comment.