]> source.dussan.org Git - jquery.git/commitdiff
Core: restore enumeration behavior in isPlainObject
authorTimmy Willison <timmywillisn@gmail.com>
Thu, 3 Mar 2016 23:29:45 +0000 (18:29 -0500)
committerTimmy Willison <timmywillisn@gmail.com>
Mon, 7 Mar 2016 16:23:33 +0000 (11:23 -0500)
Fixes gh-2968
Close gh-2970

src/core.js
test/unit/core.js

index f2730658703a15b96853fa74391432db72cf414c..967fa8e26cff8d2cadf294c23605a24a8847f6f6 100644 (file)
@@ -223,6 +223,7 @@ jQuery.extend( {
        },
 
        isPlainObject: function( obj ) {
+               var key;
 
                // Not plain objects:
                // - Any object or value whose internal [[Class]] property is not "[object Object]"
@@ -237,9 +238,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 ) {
index accdae8e1d33bde3c1c214a9cd8077e9373d7d5f..e33f653588bba073187d57d78c5e95974b5310d4 100644 (file)
@@ -268,13 +268,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" );
@@ -302,6 +310,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" );