values sobreescribir separado por objeto metodo imprimir convertir comas arreglo array javascript

javascript - sobreescribir - Implementando el método toSource() de Mozilla en Internet Explorer



prototype tostring javascript (8)

¿Alguien ha implementado el método Object.toSource () de Mozilla para Internet Explorer y otros navegadores que no son Gecko? Estoy buscando una forma liviana de serializar objetos simples en cadenas.


Considere lo siguiente: (cuando se usa FireFox 3.6)

javascript: x=function(){alert(''caveat compter'')}; alert([''JSON:/t'',JSON.stringify(x),''/n/ntoSource():/t'',x.toSource()].join(''''));

que muestra:

JSON:

toSource (): (función () {alerta ("compilación de advertencias");})

o incluso:

javascript: x=[];x[3]=x; alert(''toSource():/t''+x.toSource()); alert(''JSON can not handle this at all and goes "infinite".''); alert(''JSON:/n''+JSON.stringify(x));

que muestra:

toSource (): # 1 = [,,, # 1 #]

y el mensaje "going ''infinite''" de donde sigue la digresión recursiva de de JSON.

Los ejemplos enfatizan las sutilezas de la expresión explícitamente excluida de la representación JSON que son representadas por toSource ().

No es fácil componer un programa para replicar los mismos resultados, para TODOS los casos, como la primitiva Gecko toSource (), que es excepcionalmente poderosa.

A continuación se muestran algunos de los ''objetivos móviles'' que un programa que duplica a la funcionalidad de fuente () DEBE manejar con éxito:

javascript: function render(title,src){ (function(objRA){ alert([ title, src, ''/ntoSource():'',objRA.toSource(), ''/nJSON:'',JSON.stringify(objRA) ].join(''/n'')); })(eval(src)); } render(''Simple Raw Object source code:'', ''[new Array, new Object, new Number, new String, '' + ''new Boolean, new Date, new RegExp, new Function]'' ); render( ''Literal Instances source code:'', ''[ [], 1, true, {}, "", /./, new Date(), function(){} ]'' ); render( ''some predefined entities:'', ''[JSON, Math, null, Infinity, NaN, '' + ''void(0), Function, Array, Object, undefined]'' );

que muestra:

Simple Raw Object source code: [new Array, new Object, new Number, new String, new Boolean, new Date, new RegExp, new Function] toSource(): [[], {}, (new Number(0)), (new String("")), (new Boolean(false)), (new Date(1302637995772)), /(?:)/, (function anonymous() {})] JSON: [[],{},0,"",false,"2011-04-12T19:53:15.772Z",{},null]

y luego muestra:

Literal Instances source code: [ [], 1, true, {}, "", /./, new Date(), function(){} ] toSource(): [[], 1, true, {}, "", /./, (new Date(1302638514097)), (function () {})] JSON: [[],1,true,{},"",{},"2011-04-12T20:01:54.097Z",null]

y por último:

some predefined entities: [JSON, Math, null, Infinity, NaN, void(0), Function, Array, Object, undefined] toSource(): [JSON, Math, null, Infinity, NaN, (void 0), function Function() {[native code]}, function Array() {[native code]}, function Object() {[native code]}, (void 0)] JSON: [{},{},null,null,null,null,null,null,null,null]

El análisis anterior es significativo si las traducciones son ''para ser usadas'' o menos estrictas si se necesita un consumo humano benigno simple para ver las partes internas de un objeto. Una función JSON primaria, como representación, es la transferencia de cierta información estructurada "para ser utilizada" entre entornos.

La calidad de una función toSource () es un factor en la semántica de denotación de un programa que influye, pero no se limita a:
cálculos de ida y vuelta, menos propiedades de punto fijo y funciones inversas.

  • ¿La repetición de la conversión del código queda inactiva a un estado estático?
  • ¿Obj.toSource () == eval (eval (eval (obj.toSource ()). ToSource ()). ToSource ()). ToSource ()?
  • ¿Tiene sentido considerar si obj == eval (obj.toSource ())?
  • ¿Deshacer el resultado de una conversión, no solo un objeto similar, sino uno IDÉNTICO?
    Esta es una pregunta cargada con profundas implicaciones al clonar un objeto operacional.

y muchos muchos mas ...

Tenga en cuenta que las preguntas anteriores adquieren un significado adicional cuando obj contiene un objeto de código ejecutado, como (nueva Función ...) ()!



No tiene que usar toSource() ; Envuelva el código que se serializará en una función que devuelva la estructura JSON, y use la function#toString() lugar:

var serialized = function () { return { n: 8, o: null, b: true, s: ''text'', a: [''a'', ''b'', ''c''], f: function () { alert(''!'') } } }; serialized.toString();

Vea una demostración en vivo en jsFiddle .


Para llevar esto un poco más allá: cuando envía algo, para trabajar, un receptor debe obtenerlo y poder trabajar en él. Entonces, este próximo bit de código hará el truco, adaptado de la respuesta anterior de Eliran Malka .

// SENDER IS WRAPPING OBJECT TO BE SENT AS STRING // object to serialize var s1 = function (str) { return { n: 8, o: null, b: true, s: ''text'', a: [''a'', ''b'', ''c''], f: function () { alert(str) } } }; // test s1("this function call works!").f(); // serialized object; for newbies: object is now a string and can be sent ;) var code = s1.toString(); // RECEIVER KNOWS A WRAPPED OBJECT IS COMING IN // you have to assign your wrapped object to somevar eval(''var s2 = '' + code); // and then you can test somevar again s2("this also works!").f();

Tenga en cuenta el uso de eval . Si posee todo el código que se transfiere: siéntase libre de usarlo (aunque también puede tener desventajas). Si no sabe de dónde viene la fuente, es un no-no.

javascript object tosource stringify eval


Podrías hacer algo como esto:

Object.prototype.getSource = function() { var output = [], temp; for (var i in this) { if (this.hasOwnProperty(i)) { temp = i + ":"; switch (typeof this[i]) { case "object" : temp += this[i].getSource(); break; case "string" : temp += "/"" + this[i] + "/""; // add in some code to escape quotes break; default : temp += this[i]; } output.push(temp); } } return "{" + output.join() + "}"; }


Si el objetivo no es igualar el formato de serialización exacto de Firefox, puede usar una de las bibliotecas de serialización / deserialización JSON de JavaScript listadas en http://json.org . Usar un esquema estándar como JSON puede ser mejor que imitar el formato propietario de Gecko.


Si necesita serializar objetos con referencias circulares, puede usar la extensión cycle.js al objeto JSON de Douglas Crockford disponible en https://github.com/douglascrockford/JSON-js . Esto funciona de forma muy parecida a toSource (), aunque no serializará las funciones (pero probablemente podría adaptarse al uso del método toString de una función).


Ver también formato de datos JavaScript / bonita impresora . Creo que la rutina se exporta en formato JS válido, por lo que se puede evaluar para recuperarlo.

[EDITAR] ¡En realidad, no! Está bien para el volcado rápido pero no para la serialización real. Lo mejoré, resultado a continuación:

function SerializeObject(obj, indentValue) { var hexDigits = "0123456789ABCDEF"; function ToHex(d) { return hexDigits[d >> 8] + hexDigits[d & 0x0F]; } function Escape(string) { return string.replace(/[/x00-/x1F''//]/g, function (x) { if (x == "''" || x == "//") return "//" + x; return "//x" + ToHex(String.charCodeAt(x, 0)); }) } var indent; if (indentValue == null) { indentValue = ""; indent = ""; // or " " } else { indent = "/n"; } return GetObject(obj, indent).replace(/,$/, ""); function GetObject(obj, indent) { if (typeof obj == ''string'') { return "''" + Escape(obj) + "'',"; } if (obj instanceof Array) { result = indent + "["; for (var i = 0; i < obj.length; i++) { result += indent + indentValue + GetObject(obj[i], indent + indentValue); } result += indent + "],"; return result; } var result = ""; if (typeof obj == ''object'') { result += indent + "{"; for (var property in obj) { result += indent + indentValue + "''" + Escape(property) + "'' : " + GetObject(obj[property], indent + indentValue); } result += indent + "},"; } else { result += obj + ","; } return result.replace(/,(/n?/s*)([/]}])/g, "$1$2"); } }

indentValue puede ser nulo, "", "", "/ t" o lo que sea. Si es nulo, sin sangría, produce un resultado bastante compacto (podría usar menos espacios ...).

Podría usar una matriz para apilar los resultados y luego unirlos, pero a menos que tengas objetos gigantes, la concatenación de cadenas debería ser lo suficientemente buena ...
Además, no maneja referencias cíclicas ...