在 Chrome 开发工具中有没有自动展开对象的方法?

每一次我在控制台中查看一个对象,我想要展开它,所以每一次点击箭头来做这件事是很烦人的:)是否有一个快捷方式或设置来自动完成这件事?

65656 次浏览

也许不是最好的答案,但是我一直在用我的代码做这件事。

更新 :

使用 JSON.stringify自动展开对象:

> a = [{name: 'Joe', age: 5}, {name: 'John', age: 6}]
> JSON.stringify(a, true, 2)
"[
{
"name": "Joe",
"age": 5
},
{
"name": "John",
"age": 6
}
]"

如果你不想把所有的东西都打出来,你总是可以设置一个快捷函数:

j = function(d) {
return JSON.stringify(d, true, 2)
}


j(a)

回答:

pretty = function(d)
{
var s = []
for (var k in d) {
s.push(k + ': ' + d[k])
}
console.log(s.join(', '))
}

然后,取而代之的是:

-> a = [{name: 'Joe', age: 5}, {name: 'John', age: 6}]
-> a
<- [Object, Object]

你可以:

-> a.forEach(pretty)
<- name: Joe, age: 5
name: John, age: 6

不是最好的解决方案,但对我的使用很有效。更深层的对象不起作用,所以这是可以改进的。

选项 + 点击 Mac。现在我自己发现了,这周我过得很愉快!这真是太烦人了

这是一个工作,但它为我工作。

我用于控件/小部件根据用户操作自动更新的情况。例如,在使用 twitter 的 typehead.js 时,一旦您将焦点移出窗口,下拉列表就会消失,建议也会从 DOM 中移除。

在 dev tools 中,右键单击要展开的节点,然后启用 打开...-> 子树修改,这将把您发送到调试器。一直按 F10Shift + F11直到你变异为止。一旦变异,你就可以检查了。由于调试器处于活动状态,Chrome 的用户界面是锁定的,不会关闭下拉列表,而且建议仍然保留在 DOM 中。

当动态插入的节点开始不断插入和删除布局故障排除时,非常方便。

考虑使用 Table ()

console.table output

虽然提到 JSON.stringify解决方案在大多数情况下都非常好,但是它有一些局限性

  • 它不能处理具有循环引用的项,因为 console.log可以优雅地处理这些对象。
  • 另外,如果您有一个大树,那么交互式折叠一些节点的能力可以使探索变得更容易。

这里有一个解决方案,通过创造性地(ab)使用 console.group来解决上述两个问题:

function expandedLog(item, maxDepth = 100, depth = 0){
if (depth > maxDepth ) {
console.log(item);
return;
}
if (typeof item === 'object' && item !== null) {
Object.entries(item).forEach(([key, value]) => {
console.group(key + ' : ' +(typeof value));
expandedLog(value, maxDepth, depth + 1);
console.groupEnd();
});
} else {
console.log(item);
}
}

现在播放:

expandedLog({
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
})

会给你这样的东西:

output screenshot

可以将 maxDepth的值调整到所需的级别,超过这个级别的嵌套扩展日志将回落到通常的 console.log

试着运行这样的东西:

x = { a: 10, b: 20 }
x.x = x
expandedLog(x)

enter image description here

还请注意,console.group是非标准的。

若要展开/折叠节点及其所有子节点,

Ctrl + Alt + 单击箭头图标上的 选择 + 点击

(注意,虽然 开发工具文档列出了 Ctrl + Alt + Click,但在 Windows 上只需要 Alt + Click)。

你可以通过访问 document.getElementsBy 来查看你的元素,然后右击并复制结果对象,例如:

document.getElementsByTagName('ion-app')返回 javascript 对象,这个对象可以复制粘贴到文本编辑器,并且它完全做到了这一点。

更好的是: 右键单击生成的元素-‘ Edit as html’-‘ Select all’-‘ Copy’-‘ Paste’

下面是 Lorefnon 答案的一个修改版本,它不依赖于下划线:

var expandedLog = (function(MAX_DEPTH){


return function(item, depth){


depth    = depth || 0;
isString = typeof item === 'string';
isDeep   = depth > MAX_DEPTH


if (isString || isDeep) {
console.log(item);
return;
}


for(var key in item){
console.group(key + ' : ' +(typeof item[key]));
expandedLog(item[key], depth + 1);
console.groupEnd();
}
}
})(100);

这是我的解决方案,一个函数迭代对象的所有属性,包括数组。

在这个例子中,我迭代了一个简单的多级对象:

    var point = {
x: 5,
y: 2,
innerobj : { innerVal : 1,innerVal2 : 2 },
$excludedInnerProperties : { test: 1},
includedInnerProperties : { test: 1}
};

如果属性以一个特定的后缀开始(例如,对于角对象,$) ,您还可以排除迭代

discoverProperties = function (obj, level, excludePrefix) {
var indent = "----------------------------------------".substring(0, level * 2);
var str = indent + "level " + level + "\r\n";
if (typeof (obj) == "undefined")
return "";
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var propVal;
try {
propVal = eval('obj.' + property);
str += indent + property + "(" + propVal.constructor.name + "):" + propVal + "\r\n";
if (typeof (propVal) == 'object' && level < 10 && propVal.constructor.name != "Date" && property.indexOf(excludePrefix) != 0) {
if (propVal.hasOwnProperty('length')) {
for (var i = 0; i < propVal.length; i++) {
if (typeof (propVal) == 'object' && level < 10) {
if (typeof (propVal[i]) != "undefined") {
str += indent + (propVal[i]).constructor.name + "[" + i + "]\r\n";
str += this.discoverProperties(propVal[i], level + 1, excludePrefix);
}
}
else
str += indent + propVal[i].constructor.name + "[" + i + "]:" + propVal[i] + "\r\n";
}
}
else
str += this.discoverProperties(propVal, level + 1, excludePrefix);
}
}
catch (e) {
}
}
}
return str;
};




var point = {
x: 5,
y: 2,
innerobj : { innerVal : 1,innerVal2 : 2 },
$excludedInnerProperties : { test: 1},
includedInnerProperties : { test: 1}
};


document.write("<pre>" + discoverProperties(point,0,'$')+ "</pre>");

下面是函数的输出:

level 0
x(Number):5
y(Number):2
innerobj(Object):[object Object]
--level 1
--innerVal(Number):1
--innerVal2(Number):2
$excludedInnerProperties(Object):[object Object]
includedInnerProperties(Object):[object Object]
--level 1
--test(Number):1

你也可以在任何网页中注入这个函数,复制和分析所有的属性,尝试在谷歌页面使用 chrome 命令:

discoverProperties(google,0,'$')

你也可以使用 chrome 命令复制命令的输出:

copy(discoverProperties(myvariable,0,'$'))

另一个更简单的方法是

  • 使用 JSON.stringify (jsonObject)
  • 将结果复制并粘贴到 VisualStudio 代码
  • 使用 Ctrl + K 和 Ctrl + F 格式化结果
  • 您将看到格式化的扩展对象

我已经对简单的物体试过这个了。

如果您有一个大的对象,JSON.stringfy 将给出错误 Uncatch TypeError: 将循环结构转换为 JSON ,这里有一个技巧,使用它的修改版本

JSON.stringifyOnce = function(obj, replacer, indent){
var printedObjects = [];
var printedObjectKeys = [];


function printOnceReplacer(key, value){
if ( printedObjects.length > 2000){ // browsers will not print more than 20K, I don't see the point to allow 2K.. algorithm will not be fast anyway if we have too many objects
return 'object too long';
}
var printedObjIndex = false;
printedObjects.forEach(function(obj, index){
if(obj===value){
printedObjIndex = index;
}
});


if ( key == ''){ //root element
printedObjects.push(obj);
printedObjectKeys.push("root");
return value;
}


else if(printedObjIndex+"" != "false" && typeof(value)=="object"){
if ( printedObjectKeys[printedObjIndex] == "root"){
return "(pointer to root)";
}else{
return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase()  : typeof(value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";
}
}else{


var qualifiedKey = key || "(empty key)";
printedObjects.push(value);
printedObjectKeys.push(qualifiedKey);
if(replacer){
return replacer(key, value);
}else{
return value;
}
}
}
return JSON.stringify(obj, printOnceReplacer, indent);
};

现在你可以使用 JSON.stringifyOnce(obj)

默认情况下,Chrome 和 Safari 浏览器上的控制台将输出折叠的对象,包含排序的属性键,并包含所有继承的原型链。

我个人不太喜欢。大多数开发人员需要一个没有原型链的对象的原始输出,其他任何东西都应该是可选的。折叠对象浪费开发人员的时间,因为他们需要展开它们,如果他们想要更少的输出,他们可以只记录他们需要的属性键。自动对属性键进行排序,使开发人员无法检查自己的排序是否正确,这可能会导致 bug。最后,普通的 Javascript 开发人员不会花太多时间在继承的原型链上,因此会给日志添加噪音。

如何在控制台中展开对象

推荐

  1. console.log(JSON.stringify({}, undefined, 2));

    也可以用作函数:

    console.json = object => console.log(JSON.stringify(object, undefined, 2));
    
    
    console.json({});
    
  2. “ Option + Click”(Mac 上的 Chrome)和“ Alt + Click”(Windows 上的 Chrome)
    但是,并非所有浏览器都支持它(例如 Safari) ,而且 Console 仍然打印原型链、自动排序属性键等。

不推荐

我不推荐这两个最好的答案

  1. console.table()-这只是浅层展开,不展开嵌套对象

  2. 编写一个自定义 underscore.js 函数——对于一个简单的解决方案来说,开销太大了

您可以将 JSON.stringify 打包成一个新函数,例如

jsonLog = function (msg, d) {
console.log(msg + '\n' + JSON.stringify(d, true, 2))
}

那么

jsonLog('root=', root)

FWIW. 默里

为懒人准备的

/**
* _Universal extensive multilevel logger for lazy folks_
* @param {any} value **`Value` you want to log**
* @param {number} tab **Abount of `tab`**
*/
function log(value, tab = 4) {
console.log(JSON.stringify(value, undefined, tab));
}

用法

log(anything) // [] {} 1 true null

Alt-click 将展开 Chrome 控制台中的所有子节点。