Skip to content

Instantly share code, notes, and snippets.

@rkatic
Forked from jeresig/isObjectLiteral.html
Created November 8, 2009 13:27
Show Gist options
  • Select an option

  • Save rkatic/229254 to your computer and use it in GitHub Desktop.

Select an option

Save rkatic/229254 to your computer and use it in GitHub Desktop.
isPlainObject
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>isPlainObject</title>
<style>
li.PASS { background: green; } li.FAIL { background: red; }
iframe { display: none; }
</style>
</head>
<body>
<ul id="results"></ul>
<script>
var jQuery = jQuery || { expando: "jQuery123456789" };
;(function(){
var o = {},
toString = o.toString,
hasOwn = o.hasOwnProperty,
lastOwn = jQuery.expando + ':lastOwnProperty',
undefined;
var isObjectPrototype = hasOwn ?
function( obj ) {
return hasOwn.call( obj, "isPrototypeOf" );
} :
function( obj ) {
var isPrototypeOf = obj.isPrototypeOf;
if ( isPrototypeOf ) {
if ( !( delete obj.isPrototypeOf ) ) {
return true;
}
if ( !obj.isPrototypeOf ) {
obj.isPrototypeOf = isPrototypeOf;
return true;
}
}
return false;
};
jQuery.isPlainObject = function( obj ) {
// Must be an Object.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
return false;
}
// If it look as an instance, then it must be an Object instance.
if ( obj.constructor &&
obj.constructor.prototype &&
obj.constructor.prototype.isPrototypeOf( obj ) &&
!isObjectPrototype(obj.constructor.prototype) ) {
return false;
}
// Also we have to check that all enumerable properties are own.
// Own properties are enumerated firstly,
// so if last one is own, then all others are own too.
if ( !hasOwn ) {
obj[ lastOwn ] = true;
}
// Get last enumerable property.
var prop;
for ( prop in obj ) {}
if ( hasOwn ) {
return prop === undefined || hasOwn.call( obj, prop );
} else {
delete obj[ lastOwn ];
return prop === lastOwn;
}
}
})();
if ( ({}).hasOwnProperty ) {
log("Uses hasOwnProperty");
}
(function(){
// Enumerating in order?
var m, str = document.body.innerHTML,
obj = {}, arr = [], i = 0;
while (( m = /[\s\S]{10}/g.exec(str) )) {
if ( !obj[ m[0] ] ) {
obj[ m[0] ] = true;
arr.push( m[0] );
}
}
for ( var prop in obj ) {
if ( !prop === arr[i++] ) {
var pass = ({}).hasOwnProperty ? "INFO" : "FAIL";
log("Enumerating properties out of inserting order", pass);
break;
}
}
})();
// Function serialization is not permitted
// Does not work across all browsers
Function.prototype.toString = function(){};
// The use case that we want to match
test("{}", {}, true);
// Instantiated objects shouldn't be matched
test("new Date", new Date, false);
var fn = function(){};
// Functions shouldn't be matched
test("fn", fn, false);
// Again, instantiated objects shouldn't be matched
test("new fn (no methods)", new fn, false);
// Makes the function a little more realistic
// (and harder to detect, incidentally)
fn.prototype = {someMethod: function(){}};
// Again, instantiated objects shouldn't be matched
test("new fn", new fn, false);
test("div", document.createElement("div"), false );
/* Note:
* The restriction against instantiated functions is
* due to the fact that this method will be used for
* deep-cloning an object. Instantiated objects will
* just have their reference copied over, whereas
* plain objects will need to be completely cloned.
*/
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
var doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write("<body onload='window.top.iframeDone(Object);'>");
doc.close();
function iframeDone(otherObject){
// Objects from other windows should be matched
test("new otherObject", new otherObject, true);
}
function test(msg, a, b) {
var pass = jQuery.isPlainObject(a) === b ? "PASS" : "FAIL";
log( msg, pass );
}
function log(msg, cls) {
document.getElementById("results").innerHTML +=
"<li class='" + ( cls || "INFO" ) + "'>" + msg + "</li>";
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment