2010-07-22 11 views
7

voglio essere in grado di passare una stringa letteraleDeterminare se un oggetto JavaScript è un oggetto "complesso" o semplicemente una stringa

'this is a string' 

o un oggetto JavaScript,

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

come argomento di una funzione e intraprende azioni diverse a seconda che si tratti di una stringa o di un oggetto. Come posso determinare quale è vero?

Per essere precisi, voglio eseguire un'iterazione sulle proprietà di un oggetto e analizzare se una proprietà è una stringa, ma annidare ricorsivamente se la proprietà è un oggetto. Ho capito come usare $.each() per iterare sulle proprietà dell'oggetto, ma se lo faccio con la stringa, tratta la stringa come una matrice di lettere piuttosto che come una singola cosa. Posso aggirare questo in un altro modo?

risposta

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

Ci sono metodi simili come $.isArray() o $.isFunction() all'interno del lib jQuery.

nativo JavaScript

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

Per utilizzare il modo hack'ish con toString ha il vantaggio, che è possibile identificare se si tratta di really un oggetto e un array. Entrambi, gli oggetti e gli array restituiscono object utilizzando typeof element.

Per farla breve, non è possibile fare affidamento sull'operatore typeof per distinguere il vero objects e arrays. Per questo è necessario il toString.call(). Se hai solo bisogno di sapere se si tratta di un oggetto o no, typeof va bene.

+0

A chiunque si chieda perché ho contrassegnato questa risposta corretta piuttosto che una di quelle con più voti: in questa risposta c'è un suggerimento su come soddisfare le mie esigenze usando jQuery, il che significa che non devo scrivere (o capire in dettaglio) qualsiasi implementazione per usarlo. Questa risposta offre anche buone opzioni per coprire funzioni e array. –

2

Prova l'operatore typeof. Restituirà object per gli oggetti e string per le stringhe.

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" 

Pertanto:

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

UPDATE:

Alcune ulteriori considerazioni:

  1. Vedi @Andy E's c omment sotto.

  2. typeof null restituisce "object" pure. Lo stesso vale per qualsiasi altro oggetto, inclusi gli array.

+2

+1, perché l'OP ha richiesto in modo specifico dei letterali stringa, ma ricorda che 'typeof new String (" Hello ") ==" oggetto "'. Per essere assolutamente certi, usare 'a.constructor == String'. –

+0

Non è possibile distinguere tra 'objects' /' array' e 'null' con typeof. – jAndy

+0

@jAndy: Sì vero. Ho affermato che nella mia risposta. –

4

Prova questo:

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

Grazie alla Andy E per la Tipp con argument.constructor.

+3

qual è il voto negativo? Gradirei un commento! Quindi so cosa ho fatto di sbagliato. – jigfox

+0

@Jens F. Sono d'accordo. Buona risposta. Un voto negativo qui è assolutamente inutile. Avere un +1 da me :-) –

+0

questo fallirà chiamando 'some_function (null)', dal momento che 'typeof (null) === 'object''. – jAndy

1

si può fare qualcosa di simile

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

} 
+0

si dovrebbe andare per un 'else if' ... –

+0

aggiornato! grazie per quello – AutomatedTester

1

stavo avendo un problema simile e penso di aver capito una soluzione. Ecco il mio codice di esempio per chiunque sia interessato.

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

Questo passerà attraverso tutte le proprietà di un oggetto - anche se le proprietà sono oggetti stessi - e restituisce una stringa con i seguenti valori nella sintassi del punto.

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

ho avuto l'ispirazione da DavidPirek.com - Grazie Mr. Pirek!

Problemi correlati