繁体   English   中英

在 console.log 中显示 object 属性的原始顺序

[英]Show original order of object properties in console.log

我需要进行一些调试才能看到一个 JavaScript 对象属性的原始顺序,但是(至少在 chrome devtools 中) console.log()向我显示了按字母顺序排列的 object。

前任:

var obj = {
    z: 1,
    t: 2,
    y: 3,
    a: 4,
    n: 5,
    k: 6
}

console.log(obj)显示了这一点:

Object {z: 1, t: 2, y: 3, a: 4, n: 5…}
a:4
k:6
n:5
t:2
y:3
z:1

//expected (needed ) original order
z: 1
t: 2
y: 3
a: 4
n: 5
k: 6

console.log确实对属性进行排序,在某些情况下,您可以使用保留顺序的JSON.stringify ,例如

console.log(JSON.stringify(obj, null /*replacer function */, 4 /* space */))

注意:与流行的看法相反,js对象按照OwnPropertyKeys规范维护枚举顺序(首先是整数,然后是插入顺序中的其他属性)

console.table(yourObj)的 output 以您期望的顺序输出,尽管是一个表。

警告:数字的对象键(只有数字,即使包含在引号中)在现代浏览器中总是从最少到最多排序,但是,一旦在键中遇到非数字字符,它就会忽略该键被排序. 有一些骇人听闻的变通方法可以利用这一事实,例如在所有键前面加上 _ 或其他一些非数字字符,以防止对象被自动排序。 有关更多信息,请参阅https://www.stefanjudis.com/today-i-learned/property-order-is-predictable-in-javascript-objects-since-es2015/

如果你需要记录一个非常大的对象,为了能够折叠键,另一个选择是将它转换为键值对数组。

let keepKeyOrder = function(obj) {
    if (typeof obj === 'object' && !Array.isArray(obj)) {
        let transformKey = (k) => [k, keepKeyOrder(obj[k])];
        return Object.keys(obj).map(transformKey);
    } else {
        return obj;
    }
};

console.log(keepKeyOrder({a:3,c:4,b:{b3:123,b2:234,b1:345}}));

输出:

在此输入图像描述

只是为了澄清Console.log确实排序但它也没有....

这是一个断点列表,正确的顺序(创建时)是defaultmobileMmobileLtabletdesktopM ,这就是第一行中显示的内容。

在此处输入图像描述

但是当你展开它时,它们是按字母顺序排列的。 如果你 hover 在某些东西上并查看弹出窗口,则相同。

关键是前一分钟它确实对它们进行了排序,而下一分钟则没有。 真的应该是一种选择,但似乎不是——如果你通常不关心财产秩序,这种混合行为真的会让你大吃一惊。

另一个简单的解决方案是:

console.log(Object.entries(obj).map(k=>({[k[0]]:k[1]})))

对象确实保留了插入其(非数字)键的顺序,但它们只能保证使用某些方法按该顺序迭代。 根据规范, Object.keys及其变体, JSON.stringifyfor..in循环都以未指定的顺序迭代。 这些方法都调用EnumerateObjectProperties ,它明确指出:

未指定枚举属性的机制和顺序

虽然环境通常以可预测的顺序迭代这些方法,但规范并不能保证这种行为。

但是, Object.getOwnPropertyNames (和Reflect.ownKeys ,和Object.getOwnPropertySymbols保证以特定的顺序进行迭代:升序数字键,接着按插入顺序的其他键,每[[OwnPropertyKeys]]

因此,按插入顺序记录(非数字)属性的规范保证方法将涉及使用上述方法之一,而不是Object.keys或其变体:

 var obj = { z: 1, t: 2, y: 3, a: 4, n: 5, k: 6 }; const str = '{\\n' + Object.getOwnPropertyNames(obj).map(key => ` ${key}: ${obj[key]}`).join('\\n') + '\\n}'; console.log(str); 

对于嵌套对象,您需要一个递归函数:

 var obj = { z: 1, t: 2, y: 3, a: 4, nested: { foo: 9, bar: 99, baz: 35 }, n: 5, k: 6 }; const objToArrOfLines = (obj, lines=[], leftPadding=0, keyForThisObj) => { lines.push(`${' '.repeat(leftPadding)}${keyForThisObj ? keyForThisObj + ': ' : ''}{`); Object.getOwnPropertyNames(obj).forEach((key) => { const val = obj[key]; if (typeof val === 'object') { objToArrOfLines(val, lines, leftPadding + 2, key); } else { lines.push(`${' '.repeat(leftPadding + 2)}${key}: ${val}`); } }); lines.push(`${' '.repeat(leftPadding)}}`); return lines; }; const objToStr = (obj) => { console.log(objToArrOfLines(obj).join('\\n')); }; objToStr(obj); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM