Acho que a função var_dump (ou similares, como print_r e debug_zval_dump) é uma das mais úteis para se depurar alguns problemas em PHP. Ela avalia uma ou mais variáveis ou valores, mostrando informações sobre elas (tipo, classe, etc). O var_dump, no entanto, não existe nativamente em JavaScript. Para prover esta solução em JavaScript, tentei implementar uma var_dump parecida com a de PHP. Como ela não consegue detectar recursividade infinita (quando um elemento aponta para algum que já foi mostrado), então criei o atributo "max_iteracoes", que pode ser configurado antes de se chamar a função. Com isso, a função previne loops infinitos.
Linguagem: JavaScript
Copyright 2011 Rubens Takiguti Ribeiro
Licença: LGPL 3 ou superior
/** * Versao JavaScript da funcao var_dump do PHP * @param mixed ... Qualquer valor * @return string Informacoes do valor */ function var_dump(/* ... */) { /** * Recursao do metodo var_dump * @param midex item Qualquer valor * @param int nivel Nivel de indentacao * @return string Informacoes do valor */ this.var_dump_rec = function(item, nivel) { if (var_dump.max_iteracoes > 0 && var_dump.max_iteracoes < nivel) { return this.indentar(nivel) + "*MAX_ITERACOES(" + var_dump.max_iteracoes+ ")*\n"; } if (item === null) { return this.indentar(nivel) + "NULL\n"; } else if (item === undefined) { return this.indentar(nivel) + "undefined\n"; } var str = ''; var tipo = typeof(item); switch (tipo) { case 'object': var classe = this.get_classe(item); switch (classe) { case 'Array': str += this.indentar(nivel) + "Array(" + item.length + ") {\n"; for (var i in item) { str += this.indentar(nivel + 1) + "[" + i + "] =>\n"; str += this.var_dump_rec(item[i], nivel + 1); } str += this.indentar(nivel) + "}\n"; break; case 'Number': case 'Boolean': str += this.indentar(nivel) + classe + "(" + item.toString() + ")\n"; break; case 'String': str += this.indentar(nivel) + classe + "(" + item.toString().length + ") \"" + item.toString() + "\"\n"; break; default: str += this.indentar(nivel) + "object(" + classe + ") {\n"; var exibiu = false; for (var i in item) { exibiu = true; str += this.indentar(nivel + 1) + "[" + i + "] =>\n"; try { str += this.var_dump_rec(item[i], nivel + 1); } catch (e) { str += this.indentar(nivel + 1) + "(Erro: " + e.message + ")\n"; } } if (!exibiu) { str += this.indentar(nivel + 1) + "JSON(" + JSON.stringify(item) + ")\n"; } str += this.indentar(nivel) + "}\n"; break; } break; case 'number': str += this.indentar(nivel) + "number(" + item.toString() + ")\n"; break; case 'string': str += this.indentar(nivel) + "string(" + item.length + ") \"" + item + "\"\n"; break; case 'boolean': str += this.indentar(nivel) + "boolean(" + (item ? "true" : "false") + ")\n"; break; case 'function': str += this.indentar(nivel) + "function {\n"; str += this.indentar(nivel + 1) + "[code] =>\n"; str += this.var_dump_rec(item.toString(), nivel + 1); str += this.indentar(nivel + 1) + "[prototype] =>\n"; str += this.indentar(nivel + 1) + "object(prototype) {\n"; for (var i in item.prototype) { str += this.indentar(nivel + 2) + "[" + i + "] =>\n"; str += this.var_dump_rec(item.prototype[i], nivel + 2); } str += this.indentar(nivel + 1) + "}\n"; str += this.indentar(nivel) + "}\n"; break; default: str += this.indentar(nivel) + tipo + "(" + item + ")\n"; break; } return str; }; /** * Devolve o nome da classe de um objeto * @param Object obj Objeto a ser verificado * @return string Nome da classe */ this.get_classe = function(obj) { if (obj.constructor) { return obj.constructor.toString().replace(/^.*function\s+([^\s]*|[^\(]*)\([^\x00]+$/, "$1"); } return "Object"; }; /** * Retorna espacos para indentacao * @param int nivel Nivel de indentacao * @return string Espacos de indentacao */ this.indentar = function(nivel) { var str = ''; while (nivel > 0) { str += ' '; nivel--; } return str; }; var str = ""; var argv = var_dump.arguments; var argc = argv.length; for (var i = 0; i < argc; i++) { str += this.var_dump_rec(argv[i], 0); } return str; } var_dump.prototype.max_iteracoes = 0;
A forma de usar o var_dump para JavaScript é parecida com a de PHP: basta passar um ou mais valores ou variáveis para a função. A diferença é que, ao invés de a função exibir o valor (como faz o var_dump do PHP), ela retorna o valor na forma de string. Ele pode ser mostrado com uma mensagem em window.alert(retorno), ou colocado no documento HTML (dentro de uma tag <pre> para facilitar a visualização). Veja um exemplo e, em seguida, seu resultado:
JavaScript:
window.onload = function() { // Objeto a ser avaliado var obj = new Object(); obj.indef = undefined; obj.vazio = null; obj.num1 = 3.5; obj.inf1 = Number.POSITIVE_INFINITY; obj.inf2 = Number.NEGATIVE_INFINITY; obj.str1 = 'teste'; obj.b1 = true; obj.b2 = false; obj.vet1 = ['a','b']; obj.data = new Date(); obj.num2 = new Number(2.5); obj.str2 = new String('testando'); obj.bool1 = new Boolean(true); obj.bool2 = new Boolean(false); obj.vet2 = new Array(); obj.vet2.push('a'); obj.vet2.push(5); obj.f = function() { window.alert('oi'); }; obj.f.prototype.pi = 3.14; obj.f.prototype.msg = 'oi'; obj.f.prototype.func = function() { var x = 1; }; // Obtendo informacoes de obj var dump = var_dump(obj); // Criando uma tag PRE no documento e inserindo o resultado var pre = document.createElement("pre"); pre.appendChild(document.createTextNode(dump)); document.getElementsByTagName("body").item(0).appendChild(pre); }
Resultado:
object(Object) { [indef] => undefined [vazio] => NULL [num1] => number(3.5) [inf1] => number(Infinity) [inf2] => number(-Infinity) [str1] => string(5) "teste" [b1] => boolean(true) [b2] => boolean(false) [vet1] => Array(2) { [0] => string(1) "a" [1] => string(1) "b" } [data] => object(Date) { JSON("2011-03-12T22:10:13.716Z") } [num2] => Number(2.5) [str2] => String(8) "testando" [bool1] => Boolean(true) [bool2] => Boolean(false) [vet2] => Array(2) { [0] => string(1) "a" [1] => number(5) } [f] => function { [code] => string(39) "function () { window.alert("oi"); }" [prototype] => object(prototype) { [pi] => number(3.14) [msg] => string(2) "oi" [func] => function { [code] => string(30) "function () { var x = 1; }" [prototype] => object(prototype) { } } } } }
Para especificar o número de recursões, basta atribuir um valor ao atributo max_recursoes da função var_dump, como no exemplo:
var_dump.max_recursoes = 3; var x = var_dump(obj);
7 comentários
Wonderful, thank you!
You're welcome.
great! you did a great job..!!!
I Agree Anonymous said ...
Ótimo, vai ser muito útil...
Valeus muito muito mas muito rui oh yesss
Esto es super útil, hermano!! Muchísimas gracias!!!
Postar um comentário
Nota: fique a vontade para expressar o que achou deste artigo ou do blog.
Dica: para acompanhar as respostas, acesse com uma conta do Google e marque a opção "Notifique-me".
Atenção: o blogger não permite inclusão de tags nos comentários, por isso, use algum site externo para postar seu código com dúvidas e deixe o link aqui. Exemplo: pastebin.com