I want to be able to pass either a string literal,
'this is a string'
or a javascript object,
{one: 'this', two: 'is', three: 'a', four: 'string' }
as argument to a function, and take different actions depending on whether it's a string or an object. How do I determine which is true?
To be specific, I want to iterate over the properties of an object, and do some parsing if a property is a string, but nest recursively if the property is an object. I've figured out how to use $.each()
to iterate over the properties of the object, but if I just do this with the string, it treates the string as an array of letters rather than as a single thing. Can I get around this some other way?
I want to be able to pass either a string literal,
'this is a string'
or a javascript object,
{one: 'this', two: 'is', three: 'a', four: 'string' }
as argument to a function, and take different actions depending on whether it's a string or an object. How do I determine which is true?
To be specific, I want to iterate over the properties of an object, and do some parsing if a property is a string, but nest recursively if the property is an object. I've figured out how to use $.each()
to iterate over the properties of the object, but if I just do this with the string, it treates the string as an array of letters rather than as a single thing. Can I get around this some other way?
6 Answers
Reset to default 6var data = {
foo: "I'm a string literal",
bar: {
content: "I'm within an object"
}
};
jQuery
$.each(data, function(i, element){
if($.isPlainObject(element){
// we got an object here
}
});
There are similar methods like $.isArray()
or $.isFunction()
within the jQuery lib.
Native Javascript
for(var element in data){
if(toString.call(element) === '[object Object]'){
// we got an object here
}
}
To use the hack'ish
way with toString
has the advantage, that you can identify whether it is really
an object and an array
. Both, objects and arrays would return object
by using typeof element
.
Long story short, you cannot rely on the typeof
operator to distinguish true objects
and arrays
. For that you need the toString.call()
. If you just need to know whether it is any object or not, typeof
is just fine.
var a = 'this is a string';
console.log(typeof a); // Displays: "string"
var b = {one: 'this', two: 'is', three: 'a', four: 'string' };
console.log(typeof b); // Displays: "object"
Therefore:
if (typeof yourArgument === 'string') {
// Do the string parsing
}
else if (typeof yourArgument === 'object') {
// Do the property enumeration
}
else {
// Throw exception
}
UPDATE:
Some further considerations:
See @Andy E's ment below.
typeof null
returns"object"
as well. The same applies to any other object, including arrays.
Try this:
function some_function(argument) {
if (typeof(argument) == "string" || argument.constructor == String) {
// it's a string literal
} else if (argument && typeof(argument) == "object" && argument.constructor != Array) {
// it's an object and not null
} else {
// error
}
}
Thanks to Andy E for the tipp with argument.constructor
.
Try the typeof operator. It will return object
for objects and string
for strings.
you can do something like this
function something(variableX){
if (typeof(variableX) === 'object'){
// Do something
}else if (typeof(variableX) === 'string'){
// Do something
}
}
I was having a similar problem and I think I figured out a solution. Here is my sample code for anyone who is interested.
var propToDotSyntax = function (obj) {
var parse = function (o, n) {
var a = [], t;
for (var p in o) {
if (o.hasOwnProperty(p)) {
t = o[p];
if (n !== undefined) tmp = n + '.' + p;
else tmp = p;
if (t && typeof(t) === 'object') a.push(arguments.callee(t, tmp));
else a.push(tmp + '=' + t);
}
}
return a;
};
return parse(obj).toString();
}
var i = { prop: 'string', obj: { subprop: 'substring', subobj: { subsubprop: 'subsubstring' } } };
propToDotSyntax(i);
This will go through all the properties of an object — even if the properties are objects themselves — and return a string with the following values in dot syntax.
"prop=string,obj.subprop=substring,obj.subobj.subsubprop=subsubstring"
I got the inspiration from DavidPirek. — Thanks Mr. Pirek!