Почему [c] переопределяет [b]?

Я не понимаю, почему вывод равен 456. Я думаю, что b в [b] является свойством объекта, а c является другим свойством a. Они не связаны с var b и c вообще. Но почему a.c переопределяет a.b?

var a={},
    b={key:'b'},
    c={key:'c'};

a[b]=123;
a[c]=456;

console.log(a[b] === 456); //true

Ответ 1

Это потому, что имена свойств являются строками, но ваши объекты b и c являются объектами. Поэтому они строятся:

b + ''; // "[object Object]"
c + ''; // "[object Object]"
b + '' === c + ''; // true

Так как они становятся одной и той же строкой, начальное значение переопределяется.

Вместо этого вы можете использовать ECMAScript 6 Карты, которые позволяют использовать любое значение в качестве ключей:

var a = new Map(),
    b = {key: 'b'},
    c = {key: 'c'};
a.set(b, 123);
a.set(c, 456);
a.get(b); // 123

Ответ 2

Ваши ключи преобразуются в строки. Строковое представление "[object Object]". Все, что вы делаете в обоих случаях, следующее:

a["[object Object]"] = 123;
a["[object Object]"] = 456;

Доказательство:

var a={},
    b={key:'b'},
    c={key:'c'};

a[b]=123;
a[c]=456;

console.log(Object.keys(a));

Ответ 3

Ориал прав. JS наиболее неприятным является тип данных переменной, неясный в декларации, хотя иногда и удобен.

В этом случае даже вы попробуете [a] == 456, он показывает true.

a сначала инициализируется как одномерный массив, когда вы пытаетесь использовать его в качестве карты или значения ключа, вы можете ожидать такую ​​ошибку.