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

时间:2016-08-20 13:38:07

标签: javascript console.log

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

例如:

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

5 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分:1)

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

$ screenresolution get
2018-04-20 10:00:14.935 screenresolution[12084:518367] starting screenresolution argv=screenresolution get 
2018-04-20 10:00:14.938 screenresolution[12084:518367] Display 0: 2560x1440x32@0
2018-04-20 10:00:14.939 screenresolution[12084:518367] Display 1: 1440x2560x32@60

输出:

enter image description here

答案 2 :(得分:1)

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

  

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

尽管对于这些方法,环境通常总是以可预测的顺序进行迭代,但是规范并不能保证这种行为。

但是,保证Object.getOwnPropertyNames(以及Reflect.ownKeysObject.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);

答案 3 :(得分:1)

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

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

enter image description here

但是当您展开它时,它们是按字母顺序排列的。如果您将鼠标悬停在某物上并查看弹出窗口,则相同。

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

答案 4 :(得分:0)

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

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