(Esto se ha agregado a mi biblioteca en GitHub )
¡Reinventando la rueda aquí! Ninguna de estas soluciones funcionó para mi situación. Entonces, rápidamente modifiqué la respuesta de wilsonpage . Este no es para imprimir en la pantalla (a través de la consola, o campo de texto o lo que sea). Funciona bien en esas situaciones y funciona tan bien como lo solicitó el OP alert
. Muchas respuestas aquí no abordan el uso alert
como lo solicitó el OP. De todos modos, sin embargo, está formateado para el transporte de datos. Esta versión parece devolver un resultado muy similar al toSource()
. No lo he probado JSON.stringify
, pero supongo que esto es casi lo mismo. Esta versión es más como un poly-fil para que pueda usarlo en cualquier entorno. El resultado de esta función es una declaración de objeto Javascript válida.
No dudaría si algo así ya estaba en SO en alguna parte, pero fue más corto hacerlo que pasar un tiempo buscando respuestas pasadas. Y dado que esta pregunta fue mi mayor éxito en Google cuando comencé a buscar sobre esto; Pensé que ponerlo aquí podría ayudar a otros.
De todos modos, el resultado de esta función será una representación de cadena de su objeto, incluso si su objeto tiene objetos y matrices incrustados, e incluso si esos objetos o matrices tienen aún más objetos y matrices incrustados. (¿Te escuché que te gusta beber? Así que le piminé a tu auto con un enfriador. Y luego, pimé tu enfriador con un enfriador. Por lo tanto, tu enfriador puede beber, mientras tú eres frío).
Las matrices se almacenan en []
lugar de {}
y, por lo tanto, no tienen pares clave / valor, solo valores. Al igual que las matrices regulares. Por lo tanto, se crean como lo hacen las matrices.
Además, se citan todas las cadenas (incluidos los nombres de las teclas), esto no es necesario a menos que esas cadenas tengan caracteres especiales (como un espacio o una barra inclinada). Pero, no tenía ganas de detectar esto solo para eliminar algunas citas que de otro modo funcionarían bien.
Esta cadena resultante se puede usar con eval
o simplemente volcarla en una manipulación de var a través de cadena. Por lo tanto, volver a crear su objeto nuevamente, a partir del texto.
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)+"]";
}
Avíseme si lo arruiné todo, funciona bien en mis pruebas. Además, la única forma en que podía pensar para detectar el tipo array
era verificar la presencia de length
. Debido a que Javascript realmente almacena matrices como objetos, en realidad no puedo verificar el tipo array
(¡no existe ese tipo!). Si alguien más conoce una mejor manera, me encantaría escucharla. Porque, si su objeto también tiene una propiedad llamada length
, esta función lo tratará erróneamente como una matriz.
EDITAR: Se agregó verificación para objetos con valor nulo. Gracias Brock Adams
EDITAR: A continuación se muestra la función fija para poder imprimir objetos infinitamente recursivos. Esto no imprime lo mismo que toSource
desde FF porque toSource
imprimirá la recursión infinita una vez, mientras que esta función la matará de inmediato. Esta función se ejecuta más lentamente que la anterior, así que la agrego aquí en lugar de editar la función anterior, ya que solo es necesaria si planea pasar objetos que se vinculan a sí mismos, en algún lugar.
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)+"]";
}
Prueba:
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());
Resultado:
{'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: Intentar imprimir document.body
es un ejemplo terrible. Por un lado, FF simplemente imprime una cadena de objeto vacía cuando se usa toSource
. Y cuando se usa la función anterior, FF se bloquea SecurityError: The operation is insecure.
. Y Chrome se bloqueará Uncaught RangeError: Maximum call stack size exceeded
. Claramente, document.body
no estaba destinado a convertirse en cadena. Porque es demasiado grande o contra la política de seguridad para acceder a ciertas propiedades. A menos que haya estropeado algo aquí, ¡cuéntalo!