Update: After writing all of the below and later giving it further thought, I'd like to suggest that you take another look at Trevor's answer. I think it is more deserving of that beautiful green checkmark than my answer, and here's why.
I took your question at face value and ran with it: If you really want to do literally what you said, a function like $.isPlainObject()
is the way to go. But is that really what you need to do? Keep in mind that $.isPlainObject()
is not a very efficient function; it enumerates through all your object's properties. And as I noted below, it can't distinguish between {}
and new Object()
.
Instead of all that, Trevor suggests simply checking for the properties you need, and for most cases, most of the time, I think he's right. It's definitely closer to the approach I take in my own code: validate what I need, ignore the rest.
So do take another look at his answer and carefully consider it. (And I won't be offended if you move the checkmark!)
Now my original answer:
There's a $.isPlainObject()
function in jQuery. If you're not using jQuery, you can copy the source code for this function into your app. Open the jQuery source and search for isPlainObject:
.
It's worth reading the source for this function in any case, to see that it isn't as simple as an typeof
or instanceOf
check:
isPlainObject: function( obj ) {
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
try {
// Not own constructor property must be Object
if ( obj.constructor &&
!core_hasOwn.call(obj, "constructor") &&
!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
} catch ( e ) {
// IE8,9 Will throw exceptions on certain host objects #9897
return false;
}
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key;
for ( key in obj ) {}
return key === undefined || core_hasOwn.call( obj, key );
},
type: function( obj ) {
if ( obj == null ) {
return String( obj );
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ core_toString.call(obj) ] || "object" :
typeof obj;
},
isWindow: function( obj ) {
return obj != null && obj == obj.window;
},
And there is also the class2type
object that this code uses:
// [[Class]] -> type pairs
class2type = {},
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
(These code snippets are out of context; you'd need to tweak the syntax if you were using them standalone.)
Of course depending on the circumstances, you may not need all of these checks. And if you're using jQuery already, you can just call $.isPlainObject()
and not sweat the details.
Also note that it is not possible to distinguish an object literal from an object created with new Object
:
var obj1 = { a:'b', c:'d' };
var obj2 = new Object();
obj2.a = 'b';
obj2.c = 'd';
console.log( $.isPlainObject(obj1) ); // prints true
console.log( $.isPlainObject(obj2) ); // also prints true!
They both return true
from $.isPlainObject()
, and I'm pretty sure that any other test you devise will be unable to tell which is which either.
A funny historical note: When John Resig added this function to jQuery back in 2009, he was originally going to call it $.isObjectLiteral()
. At my urging he changed the name to $.isPlainObject
because of this ambiguity.