Câu trả lời được chấp nhận không hoạt động đối với tôi cho các đối tượng lồng nhau vì một số lý do. Điều này khiến tôi phải viết mã của riêng mình. Khi tôi viết bài này vào cuối năm 2019, có một số tùy chọn khác có sẵn trong ngôn ngữ.
Cập nhật: Tôi tin rằng câu trả lời của David Furlong là một cách tiếp cận thích hợp hơn cho nỗ lực trước đó của tôi và tôi đã phản bác lại điều đó. Của tôi dựa trên sự hỗ trợ cho Object.entries (...), vì vậy không hỗ trợ Internet Explorer.
function normalize(sortingFunction) {
return function(key, value) {
if (typeof value === 'object' && !Array.isArray(value)) {
return Object
.entries(value)
.sort(sortingFunction || undefined)
.reduce((acc, entry) => {
acc[entry[0]] = entry[1];
return acc;
}, {});
}
return value;
}
}
JSON.stringify(obj, normalize(), 2);
-
GIỮ PHIÊN BẢN CŨ NÀY ĐỂ THAM KHẢO LỊCH SỬ
Tôi thấy rằng một mảng phẳng, đơn giản của tất cả các phím trong đối tượng sẽ hoạt động. Trong hầu hết các trình duyệt (có thể dự đoán được không phải Edge hay Internet explorer) và Node 12+, có một giải pháp khá ngắn gọn là Array.prototype.flatMap (...) hiện có sẵn. (Tương đương với lodash cũng sẽ hoạt động.) Tôi chỉ thử nghiệm trong Safari, Chrome và Firefox, nhưng không hiểu lý do gì mà nó không hoạt động ở bất kỳ nơi nào khác hỗ trợ flatMap và JSON.stringify (...) .
function flattenEntries([key, value]) {
return (typeof value !== 'object')
? [ [ key, value ] ]
: [ [ key, value ], ...Object.entries(value).flatMap(flattenEntries) ];
}
function sortedStringify(obj, sorter, indent = 2) {
const allEntries = Object.entries(obj).flatMap(flattenEntries);
const sorted = allEntries.sort(sorter || undefined).map(entry => entry[0]);
return JSON.stringify(obj, sorted, indent);
}
Với điều này, bạn có thể xâu chuỗi mà không có sự phụ thuộc của bên thứ ba và thậm chí chuyển vào thuật toán sắp xếp của riêng bạn để sắp xếp các cặp mục nhập khóa-giá trị, vì vậy bạn có thể sắp xếp theo khóa, trọng tải hoặc kết hợp cả hai. Hoạt động cho các đối tượng, mảng lồng nhau và bất kỳ hỗn hợp nào của các kiểu dữ liệu cũ thuần túy.
const obj = {
"c": {
"z": 4,
"x": 3,
"y": [
2048,
1999,
{
"x": false,
"g": "help",
"f": 5
}
]
},
"a": 2,
"b": 1
};
console.log(sortedStringify(obj, null, 2));
Bản in:
{
"a": 2,
"b": 1,
"c": {
"x": 3,
"y": [
2048,
1999,
{
"f": 5,
"g": "help",
"x": false
}
],
"z": 4
}
}
Nếu bạn phải có khả năng tương thích với các công cụ JavaScript cũ hơn , bạn có thể sử dụng các phiên bản dài dòng hơn một chút để mô phỏng hành vi flatMap. Ứng dụng khách phải hỗ trợ ít nhất ES5, vì vậy không có Internet Explorer 8 trở xuống.
Chúng sẽ trả về kết quả tương tự như trên.
function flattenEntries([key, value]) {
if (typeof value !== 'object') {
return [ [ key, value ] ];
}
const nestedEntries = Object
.entries(value)
.map(flattenEntries)
.reduce((acc, arr) => acc.concat(arr), []);
nestedEntries.unshift([ key, value ]);
return nestedEntries;
}
function sortedStringify(obj, sorter, indent = 2) {
const sortedKeys = Object
.entries(obj)
.map(flattenEntries)
.reduce((acc, arr) => acc.concat(arr), [])
.sort(sorter || undefined)
.map(entry => entry[0]);
return JSON.stringify(obj, sortedKeys, indent);
}