From: Timmy Willison Date: Thu, 3 Mar 2016 23:29:45 +0000 (-0500) Subject: Core: restore enumeration behavior in isPlainObject X-Git-Tag: 3.0.0-rc1~67 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=00575d4d8c7421c5119f181009374ff2e7736127;p=jquery.git Core: restore enumeration behavior in isPlainObject Fixes gh-2968 Close gh-2970 --- diff --git a/src/core.js b/src/core.js index b10128c7a..17673dfac 100644 --- a/src/core.js +++ b/src/core.js @@ -225,6 +225,7 @@ jQuery.extend( { }, isPlainObject: function( obj ) { + var key; // Not plain objects: // - Any object or value whose internal [[Class]] property is not "[object Object]" @@ -239,9 +240,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 || hasOwn.call( obj, key ); }, isEmptyObject: function( obj ) { diff --git a/test/unit/core.js b/test/unit/core.js index 99b2acc45..d71539c02 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -286,13 +286,21 @@ QUnit.test( "type for `Symbol`", 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() {}; // The use case that we want to match 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 assert.ok( !jQuery.isPlainObject( "" ), "string" ); @@ -320,6 +328,10 @@ QUnit.asyncTest( "isPlainObject", function( assert ) { // Again, instantiated objects shouldn't be matched 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 assert.ok( !jQuery.isPlainObject( document.createElement( "div" ) ), "DOM Element" );