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