[英]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(Object.entries(obj).map(k=>({[k[0]]:k[1]})))
对象确实保留了插入其(非数字)键的顺序,但它们只能保证使用某些方法按该顺序迭代。 根据规范, Object.keys
及其变体, JSON.stringify
和for..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.