Show original order of object properties in console.log

假装没事ソ 提交于 2019-12-17 20:35:09

问题


I need for some debugging to see the original order of one JavaScript object's properties but (at least in chrome devtools) console.log() shows me an alphabetically ordered object.

Ex:

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

console.log(obj) shows this:

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

回答1:


console.log does indeed sort the properties, in some cases you can use JSON.stringify which preserves the order, e.g.

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

NB: contrary to the popular belief, js objects maintain the enumeration order, as per the OwnPropertyKeys specification (integers first, then other properties in insertion order)




回答2:


If you need to log a very big object, to be able to collapse keys, another option would be to transform it to key-value pair arrays.

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}}));

Outputs:




回答3:


Objects do retain the order that their (non-numeric) keys were inserted in, but they are only guaranteed to iterate in that order using certain methods. Per the specification, Object.keys and its variants, JSON.stringify, and for..in loops all iterate in an unspecified order. These methods all call EnumerateObjectProperties, which explicitly states:

The mechanics and order of enumerating the properties is not specified

While environments generally iterate in the predictable order anyway for those methods, that behavior is in no way guaranteed by the specification.

But, Object.getOwnPropertyNames (and Reflect.ownKeys, and Object.getOwnPropertySymbols) are guaranteed to iterate in a particular order: ascending numeric keys, followed by other keys in insertion order, per [[OwnPropertyKeys]].

So, a specification-guaranteed method of logging (non-numeric) properties in insertion order will involve using one of the above methods, rather than Object.keys or its variants:

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);

For nested objects, you'll need a recursive function instead:

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);



回答4:


Another easy solution would be:

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


来源:https://stackoverflow.com/questions/39054764/show-original-order-of-object-properties-in-console-log

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!