Почему при объединении двух объектов в один они автоматически сортируются?

Я пытаюсь объединить два объекта в один, но элементы автоматически сортируются. (сначала выводятся свойства, у которых ключи - это Цифры, потом идут свойства, у которых ключи - это буквы). Мне нужно наоборот.

Мне нужен новый объект , где сначала будут идти свойства , у которых ключи - Буквы, а потом уже свойства, у которых ключи - Цифры.

Я пробовал объединять через Object.assign(), spread оператор, но все равно сначала выводяться свойства, у которых ключ - это цифра.

Подскажите пожалуйста, как можно это исправить?

let letterObj = {
  A: [{ name: "one" }, { name: "two" }],
  B: [{ name: "one" }, { name: "two" }],
};

let numberObj = {
  1: [{ name: "one" }, { name: "two" }],
  2: [{ name: "one" }, { name: "two" }],
};

let concatObj = { ...letterObj, ...numberObj };

console.log(concatObj);


Ответы (1 шт):

Автор решения: UModeL

Исходный вариант - числа идут первыми с сортировкой, остальные ключи в порядке добавления:

let letterObj = {
  A: "one",
  Z: "one",
  B: "one",
};

let numberObj = {
  3: "one",
  1: "one",
  2: "one",
};

let concatObj = { ...letterObj, ...numberObj };

console.log("Исходный вариант", concatObj);


Для экспериментов создадим пару функций: одна создаёт новый объект, вторая выводит новый объект в консоль.


Делаем имена ключей строками

/* Создаём новый объект */
function fObjectsOrderedAssign(...args) {
  const newObj = {};
  args.forEach(arg => {
    Object.entries(arg).forEach(([key, value]) => {
      newObj[key] = value;
    });
  });
  return newObj;
}
/* Перебираем объект и выводим в консоль*/
function fObjectsEnum(obj) {
  Object.entries(obj).forEach(([key, value]) => {
    console.log(key, value);
  });
}

let letterObj = {
  "A": "one",
  "Z": "one",
  "B": "one",
};

let numberObj = {
  "3": "one",
  "1": "one",
  "2": "one",
};

let n = fObjectsOrderedAssign(letterObj, numberObj);
console.log("Вариант с ключами-строками", n);
fObjectsEnum(n);

Результат тот же, эффекта по-прежнему не наблюдаем :-(


Делаем имена ключей строками с добавлением префикса

/* Создаём новый объект */
function fObjectsOrderedAssign(...args) {
  const newObj = {};
  args.forEach(arg => {
    Object.entries(arg).forEach(([key, value]) => {
      newObj[`_${key}`] = value;
    });
  });
  return newObj;
}
/* Перебираем объект и выводим в консоль*/
function fObjectsEnum(obj) {
  Object.entries(obj).forEach(([key, value]) => {
    console.log(key, value);
  });
}

let letterObj = {
  A: "one",
  Z: "one",
  B: "one",
};

let numberObj = {
  3: "one",
  1: "one",
  2: "one",
};

let n = fObjectsOrderedAssign(letterObj, numberObj);
console.log("Вариант с ключами-строками и префиксами", n);
fObjectsEnum(n);

Ага. Теперь буквы там, где нужно, но числовые ключи всё ещё сортируются...


Делаем имена ключей строками с префиксами в исходных объектах

/* Создаём новый объект */
function fObjectsOrderedAssign(...args) {
  const newObj = {};
  args.forEach(arg => {
    Object.entries(arg).forEach(([key, value]) => {
      newObj[key] = value;
    });
  });
  return newObj;
}
/* Перебираем объект и выводим в консоль*/
function fObjectsEnum(obj) {
  Object.entries(obj).forEach(([key, value]) => {
    console.log(key, value);
  });
}

let letterObj = {
  "_A": "one",
  "_Z": "one",
  "_B": "one",
};

let numberObj = {
  "_3": "one",
  "_1": "one",
  "_2": "one",
};

let n = fObjectsOrderedAssign(letterObj, numberObj);
console.log("Вариант с ключами-строками и префиксами в исходных объектах", n);
fObjectsEnum(n);

Вот! Теперь всё правильно :-)


Итог

Необходимо явно задавать ключам строковый тип. Кроме того, во избежание приведения типов, добавлять префикс, и делать поправку на него. Тогда будет работать и для исходного варианта:

let letterObj = {
  "_A": "one",
  "_Z": "one",
  "_B": "one",
};

let numberObj = {
  "_3": "one",
  "_1": "one",
  "_2": "one",
};

let concatObj = { ...letterObj, ...numberObj };

console.log("Исходный вариант", concatObj);

→ Ссылка