Detect Plain Object

by sstur

JavaScript

var isPlainObject = (function() {
    var thisObjectProto = Object.prototype;
    var toString = thisObjectProto.toString;
    var allowsProto = ('__proto__' in thisObjectProto);
    
    var getOwnPropertyNames = Object.getOwnPropertyNames ||
        function(o) {
            var names = [];
            for (var name in o) names.push(name);
            return names;
        };
    var thisObjectProtoKeys = getOwnPropertyNames(thisObjectProto);
    
    function isPlainObject(x) {
        if (!x) return false;
        if (toString.call(x) !== '[object Object]') {
            return false;
        }
        if (!allowsProto) return true;
        var proto = Object.getPrototypeOf ? Object.getPrototypeOf(x) : x.__proto__;
        if (proto == null || proto === thisObjectProto) {
            return true;
        }
        if (getOwnPropertyNames(proto).join() === thisObjectProtoKeys.join()) {
            var isValid = true;
            for (var i = 0; i < thisObjectProtoKeys.length; i++) {
                var key = thisObjectProtoKeys[i];
                if (key === '__proto__') continue;
                if (typeof proto[key] === 'function' && proto[key].toString() === thisObjectProto[key].toString()) continue;
                isValid = false;
                break;
            }
            return isValid;
        }
        return false;
    }    
    
    return isPlainObject;
})();

// get some objects from another context
var iframe = document.createElement('iframe');
iframe.src = 'about:blank';
iframe.style.display = 'none';
document.body.appendChild(iframe);
var otherWindow = iframe.contentWindow;
var otherObject = new otherWindow.Object()

// test all the stuff
console.log(isPlainObject({}) === true);
console.log(isPlainObject(Object.create(null)) === true);
console.log(isPlainObject(Object.create({})) === false);
console.log(isPlainObject(Math) === false);
console.log(isPlainObject(otherObject) ===...