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.

Revisions

  1. rkatic revised this gist Jun 19, 2010. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -100,6 +100,7 @@
    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" );
    }
  2. rkatic revised this gist Jun 19, 2010. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -57,12 +57,12 @@
    jQuery.isPlainObject =
    protoOf &&
    function( obj ) {
    return obj && toString.call(obj) === "[object Object]" && !protoOf( protoOf(obj) || o );
    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__;
    return !!obj && toString.call(obj) === "[object Object]" && !(obj.__proto__ || o).__proto__;
    }
    ||
    function( obj ) {
  3. rkatic revised this gist Jun 19, 2010. 1 changed file with 11 additions and 13 deletions.
    24 changes: 11 additions & 13 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -91,22 +91,20 @@

    })();

    var o = {};
    var o = {}, fn = function(){};

    log( "Object.getPrototypeOf: " + (Object.getPrototypeOf ? "TRUE" : "FALSE") );

    log( "__proto__: " + (o.__proto__ === Object.prototype ? "TRUE" : "FALSE") );

    log( "Native hasOwnProperty: " + (o.hasOwnProperty ? "TRUE" : "FALSE") );

    ok( o.hasOwnProperty || o.isPrototypeOf, "hasOwnProperty or isPrototypeOf" );

    var fn = function(){};

    //ok( fn.prototype.constructor === fn, "fn.prototype.constructor === fn" );
    var method = Object.getPrototypeOf && "Object.getPrototypeOf"
    || o.__proto__ === Object.prototype && "__proto__";

    if ( method ) {
    log("Using: " + method);

    } else {
    ok( o.hasOwnProperty || o.isPrototypeOf, "hasOwnProperty or isPrototypeOf" );
    ok( fn.prototype.constructor === fn, "fn.prototype.constructor === fn" );
    }

    log("");
    log("------");


    // Function serialization is not permitted
  4. rkatic revised this gist Jun 19, 2010. 1 changed file with 18 additions and 2 deletions.
    20 changes: 18 additions & 2 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -32,6 +32,7 @@
    ;(function(){

    var o = {},
    protoOf = Object.getPrototypeOf,
    toString = o.toString,
    oprop = o.isPrototypeOf && "isPrototypeOf" || "hasOwnProperty",
    undefined;
    @@ -53,7 +54,18 @@
    return false;
    };

    jQuery.isPlainObject = function( obj ) {
    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;
    @@ -81,13 +93,17 @@

    var o = {};

    log( "Object.getPrototypeOf: " + (Object.getPrototypeOf ? "TRUE" : "FALSE") );

    log( "__proto__: " + (o.__proto__ === Object.prototype ? "TRUE" : "FALSE") );

    log( "Native hasOwnProperty: " + (o.hasOwnProperty ? "TRUE" : "FALSE") );

    ok( o.hasOwnProperty || o.isPrototypeOf, "hasOwnProperty or isPrototypeOf" );

    var fn = function(){};

    ok( fn.prototype.constructor === fn, "fn.prototype.constructor === fn" );
    //ok( fn.prototype.constructor === fn, "fn.prototype.constructor === fn" );


    log("");
  5. rkatic revised this gist Jun 18, 2010. 1 changed file with 5 additions and 30 deletions.
    35 changes: 5 additions & 30 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -79,36 +79,11 @@

    })();

    var native_hasOwnProperty = !!({}).hasOwnProperty;

    //var enumerating_in_order = (function(){
    // var m, prop, html = document.body.innerHTML,
    // obj = {}, arr = [], i = 0,
    // re = /[\s\S]{10,10}/g;
    //
    // while (( m = re.exec(html) )) {
    // prop = ' ' + m[0];
    // if ( !obj[ prop ] ) {
    // obj[ prop ] = true;
    // arr.push( prop );
    // }
    // }
    //
    // for ( var prop in obj ) {
    // if ( prop !== arr[i++] ) {
    // return false;
    // }
    // }
    //
    // return true;
    //})();

    log( "Native hasOwnProperty: " + native_hasOwnProperty );
    //log( "Enumerating properties in inserting order: " + enumerating_in_order );

    if ( !native_hasOwnProperty && !({}).isPrototypeOf ) {
    ok( false, "Nor hasOwnProperty, nor isPrototypeOf");
    }
    var o = {};

    log( "Native hasOwnProperty: " + (o.hasOwnProperty ? "TRUE" : "FALSE") );

    ok( o.hasOwnProperty || o.isPrototypeOf, "hasOwnProperty or isPrototypeOf" );

    var fn = function(){};

  6. rkatic revised this gist Jun 14, 2010. 1 changed file with 28 additions and 24 deletions.
    52 changes: 28 additions & 24 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -55,11 +55,11 @@

    jQuery.isPlainObject = function( obj ) {
    // Must be an Object.
    if ( !obj || toString.call(obj) !== "[object Object]" || !(oprop in obj) || obj.setInterval ) {
    if ( !obj || toString.call(obj) !== "[object Object]" || !(oprop in obj) || hasOwn.call(obj, oprop) ) {
    return false;
    }

    // If constructor is not own (obj is not a prototype), then it must be Object.
    // 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;
    @@ -81,30 +81,34 @@

    var native_hasOwnProperty = !!({}).hasOwnProperty;

    var enumerating_in_order = (function(){
    var m, prop, html = document.body.innerHTML,
    obj = {}, arr = [], i = 0,
    re = /[\s\S]{10,10}/g;

    while (( m = re.exec(html) )) {
    prop = ' ' + m[0];
    if ( !obj[ prop ] ) {
    obj[ prop ] = true;
    arr.push( prop );
    }
    }

    for ( var prop in obj ) {
    if ( prop !== arr[i++] ) {
    return false;
    }
    }

    return true;
    })();
    //var enumerating_in_order = (function(){
    // var m, prop, html = document.body.innerHTML,
    // obj = {}, arr = [], i = 0,
    // re = /[\s\S]{10,10}/g;
    //
    // while (( m = re.exec(html) )) {
    // prop = ' ' + m[0];
    // if ( !obj[ prop ] ) {
    // obj[ prop ] = true;
    // arr.push( prop );
    // }
    // }
    //
    // for ( var prop in obj ) {
    // if ( prop !== arr[i++] ) {
    // return false;
    // }
    // }
    //
    // return true;
    //})();

    log( "Native hasOwnProperty: " + native_hasOwnProperty );
    log( "Enumerating properties in inserting order: " + enumerating_in_order );
    //log( "Enumerating properties in inserting order: " + enumerating_in_order );

    if ( !native_hasOwnProperty && !({}).isPrototypeOf ) {
    ok( false, "Nor hasOwnProperty, nor isPrototypeOf");
    }

    var fn = function(){};

  7. rkatic revised this gist Jun 14, 2010. 1 changed file with 1 addition and 9 deletions.
    10 changes: 1 addition & 9 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,6 @@
    <body>
    <ul id="results"></ul>
    <script>
    try{
    function log(msg, pass) {
    document.getElementById("results").innerHTML +=
    "<li class='" + ( pass || "" ) + "'>" + msg + "</li>";
    @@ -27,20 +26,14 @@
    }


    var jQuery = jQuery || {
    expando: "jQuery123456789",
    isFunction: function(o) {
    return Object.prototype.toString.call(o) === "[object Function]";
    }
    };
    window.jQuery = window.jQuery || {};


    ;(function(){

    var o = {},
    toString = o.toString,
    oprop = o.isPrototypeOf && "isPrototypeOf" || "hasOwnProperty",
    lastOwn = jQuery.expando + ':lastOwnProperty',
    undefined;

    var hasOwn = o.hasOwnProperty || function( prop ) {
    @@ -173,7 +166,6 @@
    test("new otherObject", new otherObject, true);
    }
    }
    }catch(e){alert(e);}
    </script>
    </body>
    </html>
  8. rkatic revised this gist Jun 14, 2010. 1 changed file with 43 additions and 62 deletions.
    105 changes: 43 additions & 62 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>isPlainObject</title>
    <style>
    li.PASS { background: green; } li.FAIL { background: red; }
    li.PASS { background: #02C500; } li.FAIL { background: red; }
    iframe { display: none; }
    </style>
    </head>
    @@ -18,100 +18,77 @@
    }

    function ok( o, msg ) {
    log( msg, ( o ? "PASS" : "FAIL" ) );
    var type = o ? "PASS" : "FAIL";
    log( "("+type+") "+msg, type );
    }

    function test(msg, a, b) {
    ok( jQuery.isPlainObject(a) === b, msg );
    }


    var jQuery = jQuery || { expando: "jQuery123456789" };
    var jQuery = jQuery || {
    expando: "jQuery123456789",
    isFunction: function(o) {
    return Object.prototype.toString.call(o) === "[object Function]";
    }
    };


    ;(function(){

    var o = {},
    toString = o.toString,
    hasOwn = o.hasOwnProperty,
    oprop = o.isPrototypeOf && "isPrototypeOf" || "hasOwnProperty",
    lastOwn = jQuery.expando + ':lastOwnProperty',
    undefined;

    var isObjectPrototype = hasOwn ?
    function( obj ) {
    return hasOwn.call( obj, oprop );
    } :
    function( obj ) {
    var t = obj[ oprop ];
    var hasOwn = o.hasOwnProperty || function( prop ) {
    if ( prop in this ) {
    var value = this[ prop ];

    if ( t ) {
    if ( !( delete obj[ oprop ] ) ) {
    return true;
    }

    if ( !obj[ oprop ] ) {
    obj[ oprop ] = t;
    return true;
    }
    if ( !( delete this[ prop ] ) ) {
    return true;
    }

    return false;
    };
    if ( !(prop in this) || this[prop] !== value ) {
    this[ prop ] = value;
    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 ) {
    if ( !obj || toString.call(obj) !== "[object Object]" || !(oprop in obj) || obj.setInterval ) {
    return false;
    }

    // If it look as an instance, then it must be an Object instance.
    if ( obj.constructor &&
    obj instanceof obj.constructor &&
    !isObjectPrototype(obj.constructor.prototype) ) {
    // If constructor is not own (obj is not a prototype), 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.

    //for ( var prop in obj ) {
    // if ( !hasOwn.call(obj, prop) ) {
    // return false;
    // }
    //}
    //
    //return true;

    // 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;
    }
    return prop === undefined || hasOwn.call( obj, prop );
    }

    })();

    if ( ({}).hasOwnProperty ) {
    log("Supports hasOwnProperty");
    }

    (function(){
    // Enumerating in inserting order?
    var native_hasOwnProperty = !!({}).hasOwnProperty;

    var enumerating_in_order = (function(){
    var m, prop, html = document.body.innerHTML,
    obj = {}, arr = [], i = 0,
    re = /[\s\S]{10,10}/g;
    @@ -126,16 +103,23 @@

    for ( var prop in obj ) {
    if ( prop !== arr[i++] ) {
    var pass = ({}).hasOwnProperty ? "INFO" : "FAIL";
    log("Enumerating properties out of inserting order", pass);
    return;
    return false;
    }
    }

    log("Enumerating properties in inserting order");

    return true;
    })();

    log( "Native hasOwnProperty: " + native_hasOwnProperty );
    log( "Enumerating properties in inserting order: " + enumerating_in_order );

    var fn = function(){};

    ok( fn.prototype.constructor === fn, "fn.prototype.constructor === fn" );


    log("");


    // Function serialization is not permitted
    // Does not work across all browsers
    @@ -147,18 +131,13 @@
    // 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);

    if ( fn.prototype.constructor !== fn ) {
    log("Prototype with wrong constructor!", "FAIL");
    }


    // Makes the function a little more realistic
    // (and harder to detect, incidentally)
    @@ -167,6 +146,8 @@
    // Again, instantiated objects shouldn't be matched
    test("new fn", new fn, false);

    test("window", window, false );

    test("div", document.createElement("div"), false );

    /* Note:
  9. rkatic revised this gist Jun 13, 2010. 1 changed file with 21 additions and 16 deletions.
    37 changes: 21 additions & 16 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -12,21 +12,22 @@
    <ul id="results"></ul>
    <script>
    try{
    function log(msg, cls) {
    function log(msg, pass) {
    document.getElementById("results").innerHTML +=
    "<li class='" + ( cls || "INFO" ) + "'>" + msg + " (" + f + ")</li>";
    "<li class='" + ( pass || "" ) + "'>" + msg + "</li>";
    }

    function test(msg, a, b) {
    var pass = jQuery.isPlainObject(a) === b ? "PASS" : "FAIL";
    function ok( o, msg ) {
    log( msg, ( o ? "PASS" : "FAIL" ) );
    }

    log( msg, pass );
    function test(msg, a, b) {
    ok( jQuery.isPlainObject(a) === b, msg );
    }


    var jQuery = jQuery || { expando: "jQuery123456789" };

    var f = 0;

    ;(function(){

    @@ -67,7 +68,7 @@

    // If it look as an instance, then it must be an Object instance.
    if ( obj.constructor &&
    obj instanceof obj.constructor&&
    obj instanceof obj.constructor &&
    !isObjectPrototype(obj.constructor.prototype) ) {
    return false;
    }
    @@ -109,16 +110,17 @@
    }

    (function(){
    // Enumerating in order?
    // Enumerating in inserting order?

    var m, str, obj = {}, arr = [], i = 0,
    var m, prop, html = document.body.innerHTML,
    obj = {}, arr = [], i = 0,
    re = /[\s\S]{10,10}/g;

    while (( m = re.exec(document.body.innerHTML) )) {
    str = ' ' + m[0];
    if ( !obj[ str ] ) {
    obj[ str ] = true;
    arr.push( str );
    while (( m = re.exec(html) )) {
    prop = ' ' + m[0];
    if ( !obj[ prop ] ) {
    obj[ prop ] = true;
    arr.push( prop );
    }
    }

    @@ -150,11 +152,14 @@
    // Functions shouldn't be matched
    test("fn", fn, false);

    //log(fn.prototype.constructor===Object);

    // Again, instantiated objects shouldn't be matched
    test("new fn (no methods)", new fn, false);

    if ( fn.prototype.constructor !== fn ) {
    log("Prototype with wrong constructor!", "FAIL");
    }


    // Makes the function a little more realistic
    // (and harder to detect, incidentally)
    fn.prototype = {someMethod: function(){}};
  10. rkatic revised this gist Jun 10, 2010. 1 changed file with 55 additions and 35 deletions.
    90 changes: 55 additions & 35 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -11,31 +11,46 @@
    <body>
    <ul id="results"></ul>
    <script>
    try{
    function log(msg, cls) {
    document.getElementById("results").innerHTML +=
    "<li class='" + ( cls || "INFO" ) + "'>" + msg + " (" + f + ")</li>";
    }

    function test(msg, a, b) {
    var pass = jQuery.isPlainObject(a) === b ? "PASS" : "FAIL";

    log( msg, pass );
    }


    var jQuery = jQuery || { expando: "jQuery123456789" };

    var f = 0;

    ;(function(){

    var o = {},
    toString = o.toString,
    hasOwn = o.hasOwnProperty,
    oprop = o.isPrototypeOf && "isPrototypeOf" || "hasOwnProperty",
    lastOwn = jQuery.expando + ':lastOwnProperty',
    undefined;

    var isObjectPrototype = hasOwn ?
    function( obj ) {
    return hasOwn.call( obj, "isPrototypeOf" );
    return hasOwn.call( obj, oprop );
    } :
    function( obj ) {
    var isPrototypeOf = obj.isPrototypeOf;
    var t = obj[ oprop ];

    if ( isPrototypeOf ) {
    if ( !( delete obj.isPrototypeOf ) ) {
    if ( t ) {
    if ( !( delete obj[ oprop ] ) ) {
    return true;
    }

    if ( !obj.isPrototypeOf ) {
    obj.isPrototypeOf = isPrototypeOf;
    if ( !obj[ oprop ] ) {
    obj[ oprop ] = t;
    return true;
    }
    }
    @@ -52,14 +67,21 @@

    // If it look as an instance, then it must be an Object instance.
    if ( obj.constructor &&
    obj.constructor.prototype &&
    obj.constructor.prototype.isPrototypeOf( obj ) &&
    obj instanceof obj.constructor&&
    !isObjectPrototype(obj.constructor.prototype) ) {
    return false;
    }

    // Also we have to check that all enumerable properties are own.

    //for ( var prop in obj ) {
    // if ( !hasOwn.call(obj, prop) ) {
    // return false;
    // }
    //}
    //
    //return true;

    // Own properties are enumerated firstly,
    // so if last one is own, then all others are own too.

    @@ -83,29 +105,32 @@
    })();

    if ( ({}).hasOwnProperty ) {
    log("Uses hasOwnProperty");
    log("Supports hasOwnProperty");
    }

    (function(){
    // Enumerating in order?

    var m, str = document.body.innerHTML,
    obj = {}, arr = [], i = 0;
    var m, str, obj = {}, arr = [], i = 0,
    re = /[\s\S]{10,10}/g;

    while (( m = /[\s\S]{10}/g.exec(str) )) {
    if ( !obj[ m[0] ] ) {
    obj[ m[0] ] = true;
    arr.push( m[0] );
    while (( m = re.exec(document.body.innerHTML) )) {
    str = ' ' + m[0];
    if ( !obj[ str ] ) {
    obj[ str ] = true;
    arr.push( str );
    }
    }

    for ( var prop in obj ) {
    if ( !prop === arr[i++] ) {
    if ( prop !== arr[i++] ) {
    var pass = ({}).hasOwnProperty ? "INFO" : "FAIL";
    log("Enumerating properties out of inserting order", pass);
    break;
    return;
    }
    }

    log("Enumerating properties in inserting order");

    })();

    @@ -125,6 +150,8 @@
    // Functions shouldn't be matched
    test("fn", fn, false);

    //log(fn.prototype.constructor===Object);

    // Again, instantiated objects shouldn't be matched
    test("new fn (no methods)", new fn, false);

    @@ -148,26 +175,19 @@
    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);
    }
    var doc = iframe.contentDocument || iframe.contentWindow && iframe.contentWindow.document;

    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>";
    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);
    }
    }
    }catch(e){alert(e);}
    </script>
    </body>
    </html>
  11. rkatic revised this gist Jun 10, 2010. 2 changed files with 173 additions and 96 deletions.
    96 changes: 0 additions & 96 deletions isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -1,96 +0,0 @@
    <!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>
    173 changes: 173 additions & 0 deletions isPlainObject.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,173 @@
    <!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>
  12. rkatic revised this gist Dec 5, 2009. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@
    var hasOwnProperty = Object.prototype.hasOwnProperty;

    function isObjectLiteral(obj){
    if ( toString.call(obj) !== "[object Object]" ) {
    if ( toString.call(obj) !== "[object Object]" || typeof obj.nodeType === "number" ) {
    return false;
    }

    @@ -62,6 +62,8 @@
    // 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
  13. rkatic revised this gist Nov 12, 2009. 1 changed file with 35 additions and 25 deletions.
    60 changes: 35 additions & 25 deletions isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -1,33 +1,40 @@
    <!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>
    <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 hasOwnProp = Object.prototype.hasOwnProperty;

    var hasOwnProperty = Object.prototype.hasOwnProperty;

    function isObjectLiteral(obj){
    if ( toString.call(obj) !== "[object Object]" )
    return false;

    //own properties are iterated firstly (IE?),
    //so to speed up, we can test last one if it is not own

    var key;
    for ( key in obj ) {}

    return !key || hasOwnProp.call( obj, key );
    if ( toString.call(obj) !== "[object Object]" ) {
    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
    @@ -42,13 +49,16 @@

    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(){}};

    // Functions shouldn't be matched
    log("fn", fn, false);

    // Again, instantiated objects shouldn't be matched
    log("new fn", new fn, false);

    @@ -69,15 +79,15 @@
    doc.close();

    function iframeDone(otherObject){
    // Objects from other windows should be matched
    log("new otherObject", new otherObject, true);
    // 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>";
    "<li class='" + pass + "'>" + msg + "</li>";
    }
    </script>
    </body>
  14. rkatic revised this gist Nov 8, 2009. 1 changed file with 13 additions and 9 deletions.
    22 changes: 13 additions & 9 deletions isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -13,17 +13,21 @@
    <ul id="results"></ul>
    <script>

    function isObjectLiteral(obj){
    // Implement me!
    return false;

    // Other Solutions:
    var toString = Object.prototype.toString;
    var hasOwnProp = Object.prototype.hasOwnProperty;

    // Uses function serialization which doesn't work in all browsers
    //return /^function Object/.test( obj.constructor );

    // Doesn't work with object from other windows
    //return Object.prototype.toString.call(obj) === "[object Object]";
    function isObjectLiteral(obj){
    if ( toString.call(obj) !== "[object Object]" )
    return false;

    //own properties are iterated firstly (IE?),
    //so to speed up, we can test last one if it is not own

    var key;
    for ( key in obj ) {}

    return !key || hasOwnProp.call( obj, key );
    }

    // Function serialization is not permitted
  15. @jeresig jeresig revised this gist Jul 24, 2009. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -38,6 +38,10 @@

    var fn = function(){};

    // 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);

  16. @jeresig jeresig revised this gist Jul 23, 2009. 1 changed file with 16 additions and 0 deletions.
    16 changes: 16 additions & 0 deletions isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -30,13 +30,28 @@
    // 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", 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);

    @@ -46,6 +61,7 @@
    doc.close();

    function iframeDone(otherObject){
    // Objects from other windows should be matched
    log("new otherObject", new otherObject, true);
    }

  17. @jeresig jeresig created this gist Jul 23, 2009.
    60 changes: 60 additions & 0 deletions isObjectLiteral.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    <!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>

    function isObjectLiteral(obj){
    // Implement me!
    return false;

    // Other Solutions:

    // Uses function serialization which doesn't work in all browsers
    //return /^function Object/.test( obj.constructor );

    // Doesn't work with object from other windows
    //return Object.prototype.toString.call(obj) === "[object Object]";
    }

    // Function serialization is not permitted
    // Does not work across all browsers
    Function.prototype.toString = function(){};

    log("{}", {}, true);
    log("new Date", new Date, false);

    var fn = function(){};
    log("fn", fn, false);
    log("new fn", new fn, false);

    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){
    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>