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"/>
<!-- Online here: http://ejohn.org/files/bugs/isObjectLiteral/ -->
<title>isObjectLiteral</title>
<style>
li { background: green; } li.FAIL { background: red; }
iframe { display: none; }
</style>
</head>
<body>
<ul id="results"></ul>
<script>
var toString = Object.prototype.toString;
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isObjectLiteral(obj){
if ( toString.call(obj) !== "[object Object]" || typeof obj.nodeType === "number" ) {
return false;
}
// not own constructor property must be Object
if ( obj.constructor
&& !hasOwnProperty.call(obj, "constructor")
&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
//own properties are iterated firstly,
//so to speed up, we can test last one if it is own or not
var key;
for ( key in obj ) {}
return key === undefined || hasOwnProperty.call( obj, key );
}
// Function serialization is not permitted
// Does not work across all browsers
Function.prototype.toString = function(){};
// The use case that we want to match
log("{}", {}, true);
// Instantiated objects shouldn't be matched
log("new Date", new Date, false);
var fn = function(){};
// Functions shouldn't be matched
log("fn", fn, false);
// Again, instantiated objects shouldn't be matched
log("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
log("new fn", new fn, false);
log("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
log("new otherObject", new otherObject, true);
}
function log(msg, a, b) {
var pass = isObjectLiteral(a) === b ? "PASS" : "FAIL";
document.getElementById("results").innerHTML +=
"<li class='" + pass + "'>" + msg + "</li>";
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment