(Questo è stato aggiunto alla mia biblioteca su GitHub )
Reinventare la ruota qui! Nessuna di queste soluzioni ha funzionato per la mia situazione. Quindi, ho rapidamente risolto la risposta di Wilsonpage . Questo non è per la stampa su schermo (tramite console, campo di testo o altro). Funziona bene in quelle situazioni e funziona bene come richiesto dal PO, per alert
. Molte risposte qui non affrontano l'utilizzo alert
come richiesto dall'OP. Comunque, è, tuttavia, formattato per il trasporto di dati. Questa versione sembra restituire un risultato molto simile a toSource()
. Non ho testato contro JSON.stringify
, ma presumo che sia più o meno la stessa cosa. Questa versione è più simile a un poly-fil in modo da poterla utilizzare in qualsiasi ambiente. Il risultato di questa funzione è una dichiarazione di oggetto Javascript valida.
Non dubiterei che qualcosa del genere fosse già su SO da qualche parte, ma era solo più breve per farlo che passare un po 'di tempo a cercare le risposte passate. E dal momento che questa domanda è stata la mia migliore hit su google quando ho iniziato a cercare su questo; Ho pensato che metterlo qui potesse aiutare gli altri.
Ad ogni modo, il risultato di questa funzione sarà una rappresentazione in forma di stringa del tuo oggetto, anche se il tuo oggetto ha oggetti e matrici incorporati, e anche se tali oggetti o matrici hanno ancora oggetti e matrici incorporati. (Ho sentito che ti piace bere? Quindi, ho sfruttato la tua auto con un dispositivo di raffreddamento. E poi, ho ottimizzato il tuo dispositivo di raffreddamento con un dispositivo di raffreddamento. Quindi, il tuo dispositivo di raffreddamento può bere, mentre sei freddo.)
Le matrici vengono archiviate con []
anziché anziché {}
e quindi non hanno coppie chiave / valore, ma solo valori. Come matrici regolari. Pertanto, vengono creati come fanno gli array.
Inoltre, vengono citate tutte le stringhe (inclusi i nomi delle chiavi), ciò non è necessario a meno che quelle stringhe abbiano caratteri speciali (come uno spazio o una barra). Ma non avevo voglia di rilevarlo solo per rimuovere alcune virgolette che altrimenti avrebbero comunque funzionato bene.
Questa stringa risultante può quindi essere utilizzata con eval
o semplicemente scaricandola in una manipolazione var-through della stringa. Quindi, ricreare di nuovo l'oggetto, dal testo.
function ObjToSource(o){
if (!o) return 'null';
var k="",na=typeof(o.length)=="undefined"?1:0,str="";
for(var p in o){
if (na) k = "'"+p+ "':";
if (typeof o[p] == "string") str += k + "'" + o[p]+"',";
else if (typeof o[p] == "object") str += k + ObjToSource(o[p])+",";
else str += k + o[p] + ",";
}
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Fammi sapere se ho sbagliato tutto, funziona bene nei miei test. Inoltre, l'unico modo in cui potevo pensare di rilevare il tipo array
era verificare la presenza di length
. Poiché Javascript memorizza realmente le matrici come oggetti, non posso effettivamente verificare il tipo array
(non esiste un tipo del genere!). Se qualcun altro conosce un modo migliore, mi piacerebbe ascoltarlo. Perché, se il tuo oggetto ha anche una proprietà denominatalength
questa funzione lo tratterà erroneamente come un array.
EDIT: aggiunto controllo per oggetti con valore nullo. Grazie Brock Adams
MODIFICA: Di seguito è riportata la funzione fissa per poter stampare oggetti ricorsivi all'infinito. Questo non stampa lo stesso toSource
di FF perché toSource
stamperà l'infinita ricorsione una volta, dove, questa funzione la ucciderà immediatamente. Questa funzione è più lenta di quella sopra, quindi la sto aggiungendo qui invece di modificare la funzione sopra, poiché è necessaria solo se si prevede di passare oggetti che si collegano a se stessi, da qualche parte.
const ObjToSource=(o)=> {
if (!o) return null;
let str="",na=0,k,p;
if (typeof(o) == "object") {
if (!ObjToSource.check) ObjToSource.check = new Array();
for (k=ObjToSource.check.length;na<k;na++) if (ObjToSource.check[na]==o) return '{}';
ObjToSource.check.push(o);
}
k="",na=typeof(o.length)=="undefined"?1:0;
for(p in o){
if (na) k = "'"+p+"':";
if (typeof o[p] == "string") str += k+"'"+o[p]+"',";
else if (typeof o[p] == "object") str += k+ObjToSource(o[p])+",";
else str += k+o[p]+",";
}
if (typeof(o) == "object") ObjToSource.check.pop();
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Test:
var test1 = new Object();
test1.foo = 1;
test1.bar = 2;
var testobject = new Object();
testobject.run = 1;
testobject.fast = null;
testobject.loop = testobject;
testobject.dup = test1;
console.log(ObjToSource(testobject));
console.log(testobject.toSource());
Risultato:
{'run':1,'fast':null,'loop':{},'dup':{'foo':1,'bar':2}}
({run:1, fast:null, loop:{run:1, fast:null, loop:{}, dup:{foo:1, bar:2}}, dup:{foo:1, bar:2}})
NOTA: provare a stampare document.body
è un terribile esempio. Per uno, FF stampa solo una stringa di oggetto vuota quando si utilizza toSource
. E quando si utilizza la funzione sopra, FF si blocca SecurityError: The operation is insecure.
. E Chrome si bloccherà Uncaught RangeError: Maximum call stack size exceeded
. Chiaramente, document.body
non doveva essere convertito in stringa. Perché è troppo grande o contro la politica di sicurezza per accedere a determinate proprietà. A meno che, non abbia fatto un casino qui, dillo!