2010-07-22 12 views
7

Quiero ser capaz de pasar una cadena literal,La determinación de si un objeto Javascript es un objeto "complejo" o simplemente una cadena

'this is a string' 

o un objeto de JavaScript,

{one: 'this', two: 'is', three: 'a', four: 'string' } 

como argumento para una función, y tome diferentes acciones dependiendo de si se trata de una cadena o un objeto. ¿Cómo determino cuál es verdadero?

Para ser específico, quiero iterar sobre las propiedades de un objeto, y hacer algunos análisis si una propiedad es una cadena, pero anidar recursivamente si la propiedad es un objeto. He descubierto cómo usar $.each() para iterar sobre las propiedades del objeto, pero si hago esto con la cadena, trata la cadena como una matriz de letras en lugar de una sola cosa. ¿Puedo solucionar esto de otra manera?

Respuesta

6
var 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 
    } 
}); 

Hay métodos similares como $.isArray() o $.isFunction() dentro de la lib jQuery.

nativo Javascript

for(var element in data){ 
    if(toString.call(element) === '[object Object]'){ 
     // we got an object here 
    } 
} 

Para utilizar el modo hack'ish con toString tiene la ventaja de que se puede identificar si se trata de un objeto really y un array. Ambos, objetos y matrices devolverían object usando typeof element.

Para resumir, no puede confiar en el operador typeof para distinguir verdadero objects y arrays. Para eso necesitas el toString.call(). Si solo necesita saber si es algún objeto o no, typeof está bien.

+0

Para cualquiera que se pregunte por qué marqué esta respuesta correcta en lugar de una con más votos: en esta respuesta hay una sugerencia sobre cómo satisfacer mis necesidades usando jQuery, lo que significa que no tengo que escribir (ni entender en detalle) ninguna implementación para usarlo. Esta respuesta también ofrece buenas opciones para cubrir funciones y matrices. –

2

Pruebe el operador typeof. Devolverá object para objetos y string para cadenas.

5
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" 

Por lo tanto:

if (typeof yourArgument === 'string') { 
    // Do the string parsing 
} 
else if (typeof yourArgument === 'object') { 
    // Do the property enumeration 
} 
else { 
    // Throw exception 
} 

UPDATE:

Algunas consideraciones adicionales:

  1. Ver @Andy E's c omment a continuación.

  2. typeof null devuelve "object" también. Lo mismo se aplica a cualquier otro objeto, incluidas las matrices.

+2

+1, porque el OP preguntó específicamente sobre los literales de cadena, pero recuerda que 'typeof new String (" Hello ") ==" object "'. Para estar absolutamente seguro, use 'a.constructor == String'. –

+0

No se puede distinguir entre 'objects' /' arrays' y 'null' con typeof. – jAndy

+0

@jAndy: Sí cierto. Lo dije en mi respuesta. –

4

Prueba esto:

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 
    } 
} 

Gracias a Andy E para el Tipp con argument.constructor.

+3

¿cuál es el voto negativo? ¡Agradecería un comentario! Entonces sé lo que hice mal. – jigfox

+0

@Jens F. Acepto. Buena respuesta. Un voto abajo aquí es completamente inútil. Tengo un +1 de mí :-) –

+0

esto no podrá invocar 'some_function (null)', ya que 'typeof (null) === 'object''. – jAndy

1

se puede hacer algo como esto

function something(variableX){ 
    if (typeof(variableX) === 'object'){ 
    // Do something 
    }else if (typeof(variableX) === 'string'){ 
    // Do something 
    } 

} 
+0

debe ir por un 'else if' ... –

+0

actualizado! gracias por eso – AutomatedTester

1

que estaba teniendo un problema similar y creo que me di cuenta de una solución. Aquí está mi código de muestra para cualquiera que esté interesado.

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

Esto pasará a través de todas las propiedades de un objeto - incluso si las propiedades son objetos propios - y devolver una cadena con los siguientes valores en la sintaxis con punto.

"prop=string,obj.subprop=substring,obj.subobj.subsubprop=subsubstring" 

Me dio la inspiración de DavidPirek.com - Gracias Sr. Pírek!

Cuestiones relacionadas