Core: restore enumeration behavior in isPlainObject

Fixes gh-2968
Close gh-2970
This commit is contained in:
Timmy Willison 2016-03-03 18:29:45 -05:00
parent c5c3073531
commit 63397aaaea
2 changed files with 20 additions and 5 deletions

View File

@ -223,6 +223,7 @@ jQuery.extend( {
}, },
isPlainObject: function( obj ) { isPlainObject: function( obj ) {
var key;
// Not plain objects: // Not plain objects:
// - Any object or value whose internal [[Class]] property is not "[object Object]" // - Any object or value whose internal [[Class]] property is not "[object Object]"
@ -237,9 +238,11 @@ jQuery.extend( {
return false; return false;
} }
// If the function hasn't returned already, we're confident that // Own properties are enumerated firstly, so to speed up,
// |obj| is a plain object, created by {} or constructed with new Object // if last one is own, then all properties are own
return true; for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );
}, },
isEmptyObject: function( obj ) { isEmptyObject: function( obj ) {

View File

@ -268,13 +268,21 @@ QUnit.test( "type for `Symbol`", function( assert ) {
} ); } );
QUnit.asyncTest( "isPlainObject", function( assert ) { QUnit.asyncTest( "isPlainObject", function( assert ) {
assert.expect( 15 ); assert.expect( 19 );
var pass, iframe, doc, var pass, iframe, doc, parentObj, childObj, deep,
fn = function() {}; fn = function() {};
// The use case that we want to match // The use case that we want to match
assert.ok( jQuery.isPlainObject( {} ), "{}" ); assert.ok( jQuery.isPlainObject( {} ), "{}" );
assert.ok( jQuery.isPlainObject( new window.Object() ), "new Object" );
parentObj = { foo: "bar" };
childObj = Object.create( parentObj );
assert.ok( !jQuery.isPlainObject( childObj ), "isPlainObject(Object.create({}))" );
childObj.bar = "foo";
assert.ok( !jQuery.isPlainObject( childObj ), "isPlainObject(Object.create({}))" );
// Not objects shouldn't be matched // Not objects shouldn't be matched
assert.ok( !jQuery.isPlainObject( "" ), "string" ); assert.ok( !jQuery.isPlainObject( "" ), "string" );
@ -302,6 +310,10 @@ QUnit.asyncTest( "isPlainObject", function( assert ) {
// Again, instantiated objects shouldn't be matched // Again, instantiated objects shouldn't be matched
assert.ok( !jQuery.isPlainObject( new fn() ), "new fn" ); assert.ok( !jQuery.isPlainObject( new fn() ), "new fn" );
// Deep object
deep = { "foo": { "baz": true }, "foo2": document };
assert.ok( jQuery.isPlainObject( deep ), "Object with objects is still plain" );
// DOM Element // DOM Element
assert.ok( !jQuery.isPlainObject( document.createElement( "div" ) ), "DOM Element" ); assert.ok( !jQuery.isPlainObject( document.createElement( "div" ) ), "DOM Element" );