I have a value and want to know if it\'s an iteratable object literal, before I iterate it.
How do I do that?
Little gist, not really elegant but efficient
function _isObj( _obj ){
return ( typeof _obj === "object" && JSON.stringify( _obj ).indexOf( "{" ) == 0 );
}
Little example
function _isObj( _obj ){
return ( typeof _obj === "object" && JSON.stringify( _obj ).indexOf( "{" ) == 0 );
}
var p = document.createElement( "p" );
p.textContent = "undefined : " + _isObj( undefined );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "null : " + _isObj( null );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "boolean : " + _isObj( true );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "function : " + _isObj( function(){} );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "array : " + _isObj( [] );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "string : " + _isObj( "{}" );
document.body.appendChild( p );
document.body.appendChild( p );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "number : " + _isObj( 1 );
document.body.appendChild( p );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "object : " + _isObj( {} );
document.body.appendChild( p );
p = document.createElement( "p" );
p.textContent = "another object : " + _isObj( p );
document.body.appendChild( p );
hope this help
This works for me:
function isObject(o) {
try {
return ((typeof o == "object") && (o !== null) && (o.length === undefined));
} catch (err) {
return false;
}
}
Vanilla Javascript version of JQuery.isPlainObject function.
var class2type = {};
var toString = class2type.toString;
var getProto = Object.getPrototypeOf;
var hasOwn = class2type.hasOwnProperty;
var fnToString = hasOwn.toString;
var ObjectFunctionString = fnToString.call(Object);
function isPlainObject(obj) {
var proto, Ctor;
// Detect obvious negatives
// Use toString instead of jQuery.type to catch host objects
if (!obj || toString.call(obj) !== "[object Object]") {
return false;
}
proto = getProto(obj);
// Objects with no prototype (e.g., `Object.create( null )`) are plain
if (!proto) {
return true;
}
// Objects with prototype are plain iff they were constructed by a global Object function
Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
}
Example:
isPlainObject({}) // true
isPlainObject( "test" ) // false
I think a function like this should be native, just like Array.isArray
:
Object.isObject = function(obj) {
return obj && obj.constructor === this || false;
};
This one doesn't make function calls nor string comparisons, and doesn't reference global objects (like Object
), so it should be quite fast. I don't think this will used in performance intensive tasks though, but whatever.
I'm not totally convinced about the name... maybe something like Object.isLiteral
would be better.
It can cause problem with host objects, though, but I don't have a test ready.
Strangely, I'm seeing different values for toString() for a subclassed object depending how toString() is being called:
Object.prototype.toString.call(aThing)
"[object Object]"
aThing.toString()
"ZmPopupMenu"
That results in a false positive, so I amended it to prefer the object's toString():
var str = someObject.toString
? someObject.toString()
: Object.prototype.toString.call(someObject);
return str === '[object Object]';
This should do it for you:
if( Object.prototype.toString.call( someObject ) === '[object Object]' ) {
// do your iteration
}
From ECMAScript 5 Section 8.6.2 if you're interested:
The value of the [[Class]] internal property is defined by this specification for every kind of built-in object. The value of the [[Class]] internal property of a host object may be any String value except one of "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", and "String". The value of a [[Class]] internal property is used internally to distinguish different kinds of objects. Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString (see 15.2.4.2).