我想在JavaScript中看到对象的结构(用于调试).PHP中的var_dump有什么类似的东西吗?
大多数现代浏览器在其开发人员工具中都有一个控制台,对于这种调试很有用.
console.log(myvar);
然后,您将在控制台中获得对象/任何内容的良好映射的界面.
查看console
文档以获取更多详细信息.
最常见的方式:
console.log(object);
但是,我必须提到JSON.stringify
哪些对于在非浏览器脚本中转储变量很有用:
console.log( JSON.stringify(object) );
该JSON.stringify
功能还支持Simon Zyx指出的内置美化.
例:
var obj = {x: 1, y: 2, z: 3}; console.log( JSON.stringify(obj, null, 2) ); // spacing level = 2
上面的代码片段将打印出来:
{ "x": 1, "y": 2, "z": 3 }
在caniuse.com上,您可以查看本机支持该JSON.stringify
功能的浏览器:http://caniuse.com/json
您还可以使用Douglas Crockford库来添加JSON.stringify
对旧浏览器的支持:https://github.com/douglascrockford/JSON-js
文档JSON.stringify
:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
我希望这有帮助 :-)
我写这个JS函数dump()
就像PHP一样工作var_dump()
.要在警报窗口中dump(variable)
显示变量的内容:要在网页中显示变量的内容:dump(variable, 'body')
要获取变量的字符串:dump(variable, 'none')
/* repeatString() returns a string which has been repeated a set number of times */ function repeatString(str, num) { out = ''; for (var i = 0; i < num; i++) { out += str; } return out; } /* dump() displays the contents of a variable like var_dump() does in PHP. dump() is better than typeof, because it can distinguish between array, null and object. Parameters: v: The variable howDisplay: "none", "body", "alert" (default) recursionLevel: Number of times the function has recursed when entering nested objects or arrays. Each level of recursion adds extra space to the output to indicate level. Set to 0 by default. Return Value: A string of the variable's contents Limitations: Can't pass an undefined variable to dump(). dump() can't distinguish between int and float. dump() can't tell the original variable type of a member variable of an object. These limitations can't be fixed because these are *features* of JS. However, dump() */ function dump(v, howDisplay, recursionLevel) { howDisplay = (typeof howDisplay === 'undefined') ? "alert" : howDisplay; recursionLevel = (typeof recursionLevel !== 'number') ? 0 : recursionLevel; var vType = typeof v; var out = vType; switch (vType) { case "number": /* there is absolutely no way in JS to distinguish 2 from 2.0 so 'number' is the best that you can do. The following doesn't work: var er = /^[0-9]+$/; if (!isNaN(v) && v % 1 === 0 && er.test(3.0)) { out = 'int'; } */ break; case "boolean": out += ": " + v; break; case "string": out += "(" + v.length + '): "' + v + '"'; break; case "object": //check if null if (v === null) { out = "null"; } //If using jQuery: if ($.isArray(v)) //If using IE: if (isArray(v)) //this should work for all browsers according to the ECMAScript standard: else if (Object.prototype.toString.call(v) === '[object Array]') { out = 'array(' + v.length + '): {\n'; for (var i = 0; i < v.length; i++) { out += repeatString(' ', recursionLevel) + " [" + i + "]: " + dump(v[i], "none", recursionLevel + 1) + "\n"; } out += repeatString(' ', recursionLevel) + "}"; } else { //if object let sContents = "{\n"; let cnt = 0; for (var member in v) { //No way to know the original data type of member, since JS //always converts it to a string and no other way to parse objects. sContents += repeatString(' ', recursionLevel) + " " + member + ": " + dump(v[member], "none", recursionLevel + 1) + "\n"; cnt++; } sContents += repeatString(' ', recursionLevel) + "}"; out += "(" + cnt + "): " + sContents; } break; default: out = v; break; } if (howDisplay == 'body') { var pre = document.createElement('pre'); pre.innerHTML = out; document.body.appendChild(pre); } else if (howDisplay == 'alert') { alert(out); } return out; }
JavaScript中的var_dump等价物?简单地说,没有一个.
但是,这并不意味着你无助.像一些人建议的那样,使用Firebug(或其他浏览器中的等价物),但与其他人建议的不同,当你有一个(略微)更好的工具console.dir时,不要使用console.log:
console.dir(object)
打印对象的所有属性的交互式列表.这看起来与您在DOM选项卡中看到的视图相同.
正如其他人已经提到的,调试变量的最佳方法是使用现代浏览器的开发人员控制台(例如Chrome开发者工具,Firefox + Firebug,Opera Dragonfly (现在已经消失在新的基于Chromium(Blink)的Opera中),但作为开发人员说,"虽然我们还不能给你更多的信息,但蜻蜓还没死").
但是如果你需要另一种方法,那么有一个非常有用的网站叫做 php.js:
http://phpjs.org/
它提供了"PHP函数的JavaScript替代品" - 因此您可以像在PHP中一样使用它们.我会在这里复制粘贴相应的函数,但请注意,如果检测到一些错误,这些代码可以在原始站点上更新,所以我建议你访问phpjs.org站点!(顺便说一句.我不是该网站的附属机构,但我发现它非常有用.)
var_dump()
在JavaScript中
以下是JS替代的代码var_dump()
:
http://phpjs.org/functions/var_dump/
它取决于echo()
函数:http://phpjs.org/functions/echo/
function var_dump() {
// discuss at: http://phpjs.org/functions/var_dump/
// original by: Brett Zamir (http://brett-zamir.me)
// improved by: Zahlii
// improved by: Brett Zamir (http://brett-zamir.me)
// depends on: echo
// note: For returning a string, use var_export() with the second argument set to true
// test: skip
// example 1: var_dump(1);
// returns 1: 'int(1)'
var output = '',
pad_char = ' ',
pad_val = 4,
lgth = 0,
i = 0;
var _getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/)
.exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
var _repeat_char = function(len, pad_char) {
var str = '';
for (var i = 0; i < len; i++) {
str += pad_char;
}
return str;
};
var _getInnerVal = function(val, thick_pad) {
var ret = '';
if (val === null) {
ret = 'NULL';
} else if (typeof val === 'boolean') {
ret = 'bool(' + val + ')';
} else if (typeof val === 'string') {
ret = 'string(' + val.length + ') "' + val + '"';
} else if (typeof val === 'number') {
if (parseFloat(val) == parseInt(val, 10)) {
ret = 'int(' + val + ')';
} else {
ret = 'float(' + val + ')';
}
}
// The remaining are not PHP behavior because these values only exist in this exact form in JavaScript
else if (typeof val === 'undefined') {
ret = 'undefined';
} else if (typeof val === 'function') {
var funcLines = val.toString()
.split('\n');
ret = '';
for (var i = 0, fll = funcLines.length; i < fll; i++) {
ret += (i !== 0 ? '\n' + thick_pad : '') + funcLines[i];
}
} else if (val instanceof Date) {
ret = 'Date(' + val + ')';
} else if (val instanceof RegExp) {
ret = 'RegExp(' + val + ')';
} else if (val.nodeName) {
// Different than PHP's DOMElement
switch (val.nodeType) {
case 1:
if (typeof val.namespaceURI === 'undefined' || val.namespaceURI === 'http://www.w3.org/1999/xhtml') {
// Undefined namespace could be plain XML, but namespaceURI not widely supported
ret = 'HTMLElement("' + val.nodeName + '")';
} else {
ret = 'XML Element("' + val.nodeName + '")';
}
break;
case 2:
ret = 'ATTRIBUTE_NODE(' + val.nodeName + ')';
break;
case 3:
ret = 'TEXT_NODE(' + val.nodeValue + ')';
break;
case 4:
ret = 'CDATA_SECTION_NODE(' + val.nodeValue + ')';
break;
case 5:
ret = 'ENTITY_REFERENCE_NODE';
break;
case 6:
ret = 'ENTITY_NODE';
break;
case 7:
ret = 'PROCESSING_INSTRUCTION_NODE(' + val.nodeName + ':' + val.nodeValue + ')';
break;
case 8:
ret = 'COMMENT_NODE(' + val.nodeValue + ')';
break;
case 9:
ret = 'DOCUMENT_NODE';
break;
case 10:
ret = 'DOCUMENT_TYPE_NODE';
break;
case 11:
ret = 'DOCUMENT_FRAGMENT_NODE';
break;
case 12:
ret = 'NOTATION_NODE';
break;
}
}
return ret;
};
var _formatArray = function(obj, cur_depth, pad_val, pad_char) {
var someProp = '';
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = _repeat_char(pad_val * (cur_depth - 1), pad_char);
var thick_pad = _repeat_char(pad_val * (cur_depth + 1), pad_char);
var str = '';
var val = '';
if (typeof obj === 'object' && obj !== null) {
if (obj.constructor && _getFuncName(obj.constructor) === 'PHPJS_Resource') {
return obj.var_dump();
}
lgth = 0;
for (someProp in obj) {
lgth++;
}
str += 'array(' + lgth + ') {\n';
for (var key in obj) {
var objVal = obj[key];
if (typeof objVal === 'object' && objVal !== null && !(objVal instanceof Date) && !(objVal instanceof RegExp) &&
!
objVal.nodeName) {
str += thick_pad + '[' + key + '] =>\n' + thick_pad + _formatArray(objVal, cur_depth + 1, pad_val,
pad_char);
} else {
val = _getInnerVal(objVal, thick_pad);
str += thick_pad + '[' + key + '] =>\n' + thick_pad + val + '\n';
}
}
str += base_pad + '}\n';
} else {
str = _getInnerVal(obj, thick_pad);
}
return str;
};
output = _formatArray(arguments[0], 0, pad_val, pad_char);
for (i = 1; i < arguments.length; i++) {
output += '\n' + _formatArray(arguments[i], 0, pad_val, pad_char);
}
this.echo(output);
}
print_r()
在JavaScript中
这是print_r()
功能:
http://phpjs.org/functions/print_r/
这也取决于echo()
.
function print_r(array, return_val) {
// discuss at: http://phpjs.org/functions/print_r/
// original by: Michael White (http://getsprink.com)
// improved by: Ben Bryan
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// input by: Brett Zamir (http://brett-zamir.me)
// depends on: echo
// example 1: print_r(1, true);
// returns 1: 1
var output = '',
pad_char = ' ',
pad_val = 4,
d = this.window.document,
getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/)
.exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
repeat_char = function(len, pad_char) {
var str = '';
for (var i = 0; i < len; i++) {
str += pad_char;
}
return str;
};
formatArray = function(obj, cur_depth, pad_val, pad_char) {
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = repeat_char(pad_val * cur_depth, pad_char);
var thick_pad = repeat_char(pad_val * (cur_depth + 1), pad_char);
var str = '';
if (typeof obj === 'object' && obj !== null && obj.constructor && getFuncName(obj.constructor) !==
'PHPJS_Resource') {
str += 'Array\n' + base_pad + '(\n';
for (var key in obj) {
if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
str += thick_pad + '[' + key + '] => ' + formatArray(obj[key], cur_depth + 1, pad_val, pad_char);
} else {
str += thick_pad + '[' + key + '] => ' + obj[key] + '\n';
}
}
str += base_pad + ')\n';
} else if (obj === null || obj === undefined) {
str = '';
} else {
// for our "resource" class
str = obj.toString();
}
return str;
};
output = formatArray(array, 0, pad_val, pad_char);
if (return_val !== true) {
if (d.body) {
this.echo(output);
} else {
try {
// We're in XUL, so appending as plain text won't work; trigger an error out of XUL
d = XULDocument;
this.echo('' + output + '
');
} catch (e) {
// Outputting as plain text may work in some plain XML
this.echo(output);
}
}
return true;
}
return output;
}
var_export()
在JavaScript中
您也可以找到var_export()
有用的替代方案,这也取决于echo()
:http:
//phpjs.org/functions/var_export/
function var_export(mixed_expression, bool_return) { // discuss at: http://phpjs.org/functions/var_export/ // original by: Philip Peterson // improved by: johnrembo // improved by: Brett Zamir (http://brett-zamir.me) // input by: Brian Tafoya (http://www.premasolutions.com/) // input by: Hans Henrik (http://hanshenrik.tk/) // bugfixed by: Brett Zamir (http://brett-zamir.me) // bugfixed by: Brett Zamir (http://brett-zamir.me) // depends on: echo // example 1: var_export(null); // returns 1: null // example 2: var_export({0: 'Kevin', 1: 'van', 2: 'Zonneveld'}, true); // returns 2: "array (\n 0 => 'Kevin',\n 1 => 'van',\n 2 => 'Zonneveld'\n)" // example 3: data = 'Kevin'; // example 3: var_export(data, true); // returns 3: "'Kevin'" var retstr = '', iret = '', value, cnt = 0, x = [], i = 0, funcParts = [], // We use the last argument (not part of PHP) to pass in // our indentation level idtLevel = arguments[2] || 2, innerIndent = '', outerIndent = '', getFuncName = function(fn) { var name = (/\W*function\s+([\w\$]+)\s*\(/) .exec(fn); if (!name) { return '(Anonymous)'; } return name[1]; }; _makeIndent = function(idtLevel) { return (new Array(idtLevel + 1)) .join(' '); }; __getType = function(inp) { var i = 0, match, types, cons, type = typeof inp; if (type === 'object' && (inp && inp.constructor) && getFuncName(inp.constructor) === 'PHPJS_Resource') { return 'resource'; } if (type === 'function') { return 'function'; } if (type === 'object' && !inp) { // Should this be just null? return 'null'; } if (type === 'object') { if (!inp.constructor) { return 'object'; } cons = inp.constructor.toString(); match = cons.match(/(\w+)\(/); if (match) { cons = match[1].toLowerCase(); } types = ['boolean', 'number', 'string', 'array']; for (i = 0; i < types.length; i++) { if (cons === types[i]) { type = types[i]; break; } } } return type; }; type = __getType(mixed_expression); if (type === null) { retstr = 'NULL'; } else if (type === 'array' || type === 'object') { outerIndent = _makeIndent(idtLevel - 2); innerIndent = _makeIndent(idtLevel); for (i in mixed_expression) { value = this.var_export(mixed_expression[i], 1, idtLevel + 2); value = typeof value === 'string' ? value.replace(//g, '>'): value; x[cnt++] = innerIndent + i + ' => ' + (__getType(mixed_expression[i]) === 'array' ? '\n' : '') + value; } iret = x.join(',\n'); retstr = outerIndent + 'array (\n' + iret + '\n' + outerIndent + ')'; } else if (type === 'function') { funcParts = mixed_expression.toString() . match(/function .*?\((.*?)\) \{([\s\S]*)\}/); // For lambda functions, var_export() outputs such as the following: // '\000lambda_1'. Since it will probably not be a common use to // expect this (unhelpful) form, we'll use another PHP-exportable // construct, create_function() (though dollar signs must be on the // variables in JavaScript); if using instead in JavaScript and you // are using the namespaced version, note that create_function() will // not be available as a global retstr = "create_function ('" + funcParts[1] + "', '" + funcParts[2].replace(new RegExp("'", 'g'), "\\'") + "')"; } else if (type === 'resource') { // Resources treated as null for var_export retstr = 'NULL'; } else { retstr = typeof mixed_expression !== 'string' ? mixed_expression : "'" + mixed_expression.replace(/(["'])/g, '\\$1') . replace(/\0/g, '\\0') + "'"; } if (!bool_return) { this.echo(retstr); return null; } return retstr; }
echo()
在JavaScript中
http://phpjs.org/functions/echo/
function echo() {
// discuss at: http://phpjs.org/functions/echo/
// original by: Philip Peterson
// improved by: echo is bad
// improved by: Nate
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Brett Zamir (http://brett-zamir.me)
// revised by: Der Simon (http://innerdom.sourceforge.net/)
// bugfixed by: Eugene Bulkin (http://doubleaw.com/)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: EdorFaus
// input by: JB
// note: If browsers start to support DOM Level 3 Load and Save (parsing/serializing),
// note: we wouldn't need any such long code (even most of the code below). See
// note: link below for a cross-browser implementation in JavaScript. HTML5 might
// note: possibly support DOMParser, but that is not presently a standard.
// note: Although innerHTML is widely used and may become standard as of HTML5, it is also not ideal for
// note: use with a temporary holder before appending to the DOM (as is our last resort below),
// note: since it may not work in an XML context
// note: Using innerHTML to directly add to the BODY is very dangerous because it will
// note: break all pre-existing references to HTMLElements.
// example 1: echo('abc
abc
');
// returns 1: undefined
var isNode = typeof module !== 'undefined' && module.exports && typeof global !== "undefined" && {}.toString.call(
global) == '[object global]';
if (isNode) {
var args = Array.prototype.slice.call(arguments);
return console.log(args.join(' '));
}
var arg = '';
var argc = arguments.length;
var argv = arguments;
var i = 0;
var holder, win = this.window;
var d = win.document;
var ns_xhtml = 'http://www.w3.org/1999/xhtml';
// If we're in a XUL context
var ns_xul = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
var stringToDOM = function(str, parent, ns, container) {
var extraNSs = '';
if (ns === ns_xul) {
extraNSs = ' xmlns:html="' + ns_xhtml + '"';
}
var stringContainer = '<' + container + ' xmlns="' + ns + '"' + extraNSs + '>' + str + '' + container + '>';
var dils = win.DOMImplementationLS;
var dp = win.DOMParser;
var ax = win.ActiveXObject;
if (dils && dils.createLSInput && dils.createLSParser) {
// Follows the DOM 3 Load and Save standard, but not
// implemented in browsers at present; HTML5 is to standardize on innerHTML, but not for XML (though
// possibly will also standardize with DOMParser); in the meantime, to ensure fullest browser support, could
// attach http://svn2.assembla.com/svn/brettz9/DOMToString/DOM3.js (see http://svn2.assembla.com/svn/brettz9/DOMToString/DOM3.xhtml for a simple test file)
var lsInput = dils.createLSInput();
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
lsInput.stringData = stringContainer;
// synchronous, no schema type
var lsParser = dils.createLSParser(1, null);
return lsParser.parse(lsInput)
.firstChild;
} else if (dp) {
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
try {
var fc = new dp()
.parseFromString(stringContainer, 'text/xml');
if (fc && fc.documentElement && fc.documentElement.localName !== 'parsererror' && fc.documentElement.namespaceURI !==
'http://www.mozilla.org/newlayout/xml/parsererror.xml') {
return fc.documentElement.firstChild;
}
// If there's a parsing error, we just continue on
} catch (e) {
// If there's a parsing error, we just continue on
}
} else if (ax) {
// We don't bother with a holder in Explorer as it doesn't support namespaces
var axo = new ax('MSXML2.DOMDocument');
axo.loadXML(str);
return axo.documentElement;
}
/*else if (win.XMLHttpRequest) {
// Supposed to work in older Safari
var req = new win.XMLHttpRequest;
req.open('GET', 'data:application/xml;charset=utf-8,'+encodeURIComponent(str), false);
if (req.overrideMimeType) {
req.overrideMimeType('application/xml');
}
req.send(null);
return req.responseXML;
}*/
// Document fragment did not work with innerHTML, so we create a temporary element holder
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
//if (d.createElementNS && (d.contentType && d.contentType !== 'text/html')) {
// Don't create namespaced elements if we're being served as HTML (currently only Mozilla supports this detection in true XHTML-supporting browsers, but Safari and Opera should work with the above DOMParser anyways, and IE doesn't support createElementNS anyways)
if (d.createElementNS && // Browser supports the method
(d.documentElement.namespaceURI || // We can use if the document is using a namespace
d.documentElement.nodeName.toLowerCase() !== 'html' || // We know it's not HTML4 or less, if the tag is not HTML (even if the root namespace is null)
(d.contentType && d.contentType !== 'text/html') // We know it's not regular HTML4 or less if this is Mozilla (only browser supporting the attribute) and the content type is something other than text/html; other HTML5 roots (like svg) still have a namespace
)) {
// Don't create namespaced elements if we're being served as HTML (currently only Mozilla supports this detection in true XHTML-supporting browsers, but Safari and Opera should work with the above DOMParser anyways, and IE doesn't support createElementNS anyways); last test is for the sake of being in a pure XML document
holder = d.createElementNS(ns, container);
} else {
// Document fragment did not work with innerHTML
holder = d.createElement(container);
}
holder.innerHTML = str;
while (holder.firstChild) {
parent.appendChild(holder.firstChild);
}
return false;
// throw 'Your browser does not support DOM parsing as required by echo()';
};
var ieFix = function(node) {
if (node.nodeType === 1) {
var newNode = d.createElement(node.nodeName);
var i, len;
if (node.attributes && node.attributes.length > 0) {
for (i = 0, len = node.attributes.length; i < len; i++) {
newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i].nodeName));
}
}
if (node.childNodes && node.childNodes.length > 0) {
for (i = 0, len = node.childNodes.length; i < len; i++) {
newNode.appendChild(ieFix(node.childNodes[i]));
}
}
return newNode;
} else {
return d.createTextNode(node.nodeValue);
}
};
var replacer = function(s, m1, m2) {
// We assume for now that embedded variables do not have dollar sign; to add a dollar sign, you currently must use {$$var} (We might change this, however.)
// Doesn't cover all cases yet: see http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double
if (m1 !== '\\') {
return m1 + eval(m2);
} else {
return s;
}
};
this.php_js = this.php_js || {};
var phpjs = this.php_js;
var ini = phpjs.ini;
var obs = phpjs.obs;
for (i = 0; i < argc; i++) {
arg = argv[i];
if (ini && ini['phpjs.echo_embedded_vars']) {
arg = arg.replace(/(.?)\{?\$(\w*?\}|\w*)/g, replacer);
}
if (!phpjs.flushing && obs && obs.length) {
// If flushing we output, but otherwise presence of a buffer means caching output
obs[obs.length - 1].buffer += arg;
continue;
}
if (d.appendChild) {
if (d.body) {
if (win.navigator.appName === 'Microsoft Internet Explorer') {
// We unfortunately cannot use feature detection, since this is an IE bug with cloneNode nodes being appended
d.body.appendChild(stringToDOM(ieFix(arg)));
} else {
var unappendedLeft = stringToDOM(arg, d.body, ns_xhtml, 'div')
.cloneNode(true); // We will not actually append the div tag (just using for providing XHTML namespace by default)
if (unappendedLeft) {
d.body.appendChild(unappendedLeft);
}
}
} else {
// We will not actually append the description tag (just using for providing XUL namespace by default)
d.documentElement.appendChild(stringToDOM(arg, d.documentElement, ns_xul, 'description'));
}
} else if (d.write) {
d.write(arg);
} else {
console.log(arg);
}
}
}
萤火虫.
然后,在您的JavaScript中:
var blah = {something: 'hi', another: 'noway'}; console.debug("Here is blah: %o", blah);
现在您可以查看控制台,单击该语句并查看其中的内容 blah