MTK*_*MTK 10 javascript console.log
我需要一些调试来查看一个JavaScript对象的属性的原始顺序,但(至少在chrome devtools中)console.log()向我显示按字母顺序排列的对象.
例如:
var obj = {
z: 1,
t: 2,
y: 3,
a: 4,
n: 5,
k: 6
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
geo*_*org 18
console.log确实对属性进行排序,在某些情况下,您可以使用JSON.stringify保留顺序,例如
console.log(JSON.stringify(obj, null /*replacer function */, 4 /* space */))
Run Code Online (Sandbox Code Playgroud)
注意:与流行的看法相反,js对象按照OwnPropertyKeys规范维护枚举顺序(首先是整数,然后是插入顺序中的其他属性)
对象确实保留其(非数字)键插入的顺序,但只能保证使用某些方法按该顺序进行迭代。根据规范Object.keys及其变体,JSON.stringify和for..in循环都以未指定的顺序进行迭代。这些方法都调用EnumerateObjectProperties,其中明确指出:
未指定枚举属性的机制和顺序
虽然环境通常以可预测的顺序对这些方法进行迭代,但规范绝不能保证该行为。
但是,Object.getOwnPropertyNames(and Reflect.ownKeys、 and 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);Run Code Online (Sandbox Code Playgroud)
对于嵌套对象,您需要一个递归函数:
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);Run Code Online (Sandbox Code Playgroud)