Skip to content

Instantly share code, notes, and snippets.

@rkatic
Forked from jeresig/isObjectLiteral.html
Created November 8, 2009 13:27
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/229254 to your computer and use it in GitHub Desktop.
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: #02C500; } li.FAIL { background: red; }
iframe { display: none; }
</style>
</head>
<body>
<ul id="results"></ul>
<script>
function log(msg, pass) {
document.getElementById("results").innerHTML +=
"<li class='" + ( pass || "" ) + "'>" + msg + "</li>";
}
function ok( o, msg ) {
var type = o ? "PASS" : "FAIL";
log( "("+type+") "+msg, type );
}
function test(msg, a, b) {
ok( jQuery.isPlainObject(a) === b, msg );
}
window.jQuery = window.jQuery || {};
;(function(){
var o = {},
protoOf = Object.getPrototypeOf,
toString = o.toString,
oprop = o.isPrototypeOf && "isPrototypeOf" || "hasOwnProperty",
undefined;
var hasOwn = o.hasOwnProperty || function( prop ) {
if ( prop in this ) {
var value = this[ prop ];
if ( !( delete this[ prop ] ) ) {
return true;
}
if ( !(prop in this) || this[prop] !== value ) {
this[ prop ] = value;
return true;
}
}
return false;
};
jQuery.isPlainObject =
protoOf &&
function( obj ) {
return !!obj && toString.call(obj) === "[object Object]" && !protoOf( protoOf(obj) || o );
}
||
o.__proto__ === Object.prototype &&
function( obj ) {
return !!obj && toString.call(obj) === "[object Object]" && !(obj.__proto__ || o).__proto__;
}
||
function( obj ) {
// Must be an Object.
if ( !obj || toString.call(obj) !== "[object Object]" || !(oprop in obj) || hasOwn.call(obj, oprop) ) {
return false;
}
// If constructor is not own, then it must be Object.
if ( obj.constructor && !hasOwn.call( obj, "constructor" ) &&
obj.constructor.prototype && !hasOwn.call( obj.constructor.prototype, oprop ) ) {
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.
// Get last enumerable property.
var prop;
for ( prop in obj ) {}
return prop === undefined || hasOwn.call( obj, prop );
}
})();
var o = {}, fn = function(){};
var method = Object.getPrototypeOf && "Object.getPrototypeOf"
|| o.__proto__ === Object.prototype && "__proto__";
if ( method ) {
log("Using: " + method);
} else {
log("Native hasOwnProperty: " + (o.hasOwnProperty ? "YES" : "NO"));
ok( o.hasOwnProperty || o.isPrototypeOf, "hasOwnProperty or isPrototypeOf" );
ok( fn.prototype.constructor === fn, "fn.prototype.constructor === fn" );
}
log("------");
// 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);
// 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("window", window, 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 && iframe.contentWindow.document;
if ( doc ) {
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);
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment