Skip to content

Instantly share code, notes, and snippets.

@rkatic
Forked from jeresig/isObjectLiteral.html
Created July 30, 2009 10:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkatic/158651 to your computer and use it in GitHub Desktop.
Save rkatic/158651 to your computer and use it in GitHub Desktop.
isObjectLiteral STRICT
<!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>
if ( !Object.getPrototypeOf && ({}).__proto__ === Object.prototype ) {
Object.getPrototypeOf = function(obj) {
return obj.__proto__;
};
}
var isObjectLiteral = ( Object.getPrototypeOf ) ?
function(obj) {
if ( typeof obj !== "object" ) {
return false;
}
var proto = Object.getPrototypeOf(obj);
return !(proto && Object.getPrototypeOf(proto));
} :
(function(){
var OP = Object.prototype;
function getProto(obj) {
var c = obj.constructor;
if ( OP.hasOwnProperty.call(obj, "constructor") ) {
var t = c;
if ( !(delete obj.constructor) ) {
return null;
}
c = obj.constructor;
obj.constructor = t;
}
return c ? c.prototype : null;
}
return function(obj) {
if ( OP.toString.call(obj) !== "[object Object]" ) {
return false;
}
var proto = getProto(obj),
hasProp = OP.hasOwnProperty;
if ( !proto ) {
return true;
}
if ( !hasProp.call(proto, "hasOwnProperty") || getProto(proto) ) {
return false
}
for ( var i in obj ) {
if ( !hasProp.call(obj, i) && !(i in proto) ) {
return false;
}
}
return true;
};
})();
// 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);
log("{constructor: 1}", {constructor: 1}, true);
// Instantiated objects shouldn't be matched
log("new Date", new Date, false);
var fn = function(){};
log("new fn (with no prototype changes)", new fn, false);
// Makes the function a little more realistic
// (and harder to detect, incidentally)
fn.prototype = {someMethod: function(){}};
// Functions shouldn't be matched
log("fn", fn, false);
// Again, instantiated objects shouldn't be matched
log("new fn", new fn, 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, Date);'>");
doc.close();
function iframeDone(otherObject, otherDate){
// Objects from other windows should be matched
log("new otherObject", new otherObject, true);
log("new otherDate", new otherDate, false);
}
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