Вроде как в коде ниже и всё должно быть просто, но тем не менее принцип работы не поддаётся моему пониманию.
При присваивании foo.x = foo = obj, как я понимаю, сначала выполняется правый участок кода, то есть в переменную "foo" заносится ссылка на объект {n:2} из переменной obj, и потом в свойство "foo.x" должна вроде как заноситься аналогичная ссылка, но выходит undefined. Может кто-то объяснить из-за чего подобное происходит?
let foo = {};
let obj = {n:2};
foo.x = foo = obj;
console.log(foo.x);
console.log(foo);
console.log(obj);
Другие участники пытаются донести мысль, что при выполнении строки foo.x = foo = obj;
имена объектов сначала разыменовываются, как бы заменяются указателями на объекты.
Объектов два, давайте обозначим их A и B. Изначально foo
указывает на A, obj
на B. Тогда та строка превратится в такую последовательность действий:
Разыменование, которое превращает foo.x = ...
в нечто вроде A.x = ...
То, как это устроено, детально поясняет ответ от Igor.
Положить в переменную foo
ту же ссылку, что в переменной obj
. Теперь они обе указывают на B.
Положить в поле x
объекта A ссылку из переменной foo
. Спасибо разыменовыванию.
Вот небольшое изменение исходного кода, которое поможет лучше понять ситуацию:
let foo = {}; // A
let old_foo = foo; // сохраним A
let obj = {n:2}; // B
foo.x = foo = obj;
// foo указывает на B
// A.x = *foo = B
console.log(foo.x); // B.x = undefined
console.log(foo); // B
console.log(obj); // B
console.log(old_foo); // сохранённное A
Как показывает вывод, объект А никуда не делся, просто раньше на него была потеряна ссылка, а присвоение поля x
прошло корректно, хоть и не на тот объект, который кажется очевидным.
let holder = { _foo: {} };
Object.defineProperty(holder, 'foo', {
get() {
return this._foo;
},
set(value)
{
console.log("set foo", value);
this._foo = value;
}
});
Object.defineProperty(holder.foo, 'x', {
get() {
return this._x;
},
set(value)
{
console.log("set foo.x", value);
this._x = value;
}
});
holder.foo.x = holder.foo = {n:2};
console.log(holder);
console.log(holder.foo);
Дело в том, что объекты в JS содержат не поля, а свойства.
Представьте, что нет свойств, а есть только гетеры и сетеры:
holder.getFoo().setX((holder.setFoo({ n: 2 }), holder.getFoo()));
Функция setX
вызовется, хотя метода setX
у результа вызова holder.getFoo
в этот момент уже не будет.
Потому что foo.x
изначально undefined, а раз выскочил undefined, то js его сразу вернет и продолжит выполнение следующих команд. Так что нужно что-то запихнуть в свойство foo.x
.
Например вот так
let foo = {};
let obj = {
n: 2
};
foo.x = obj.n;
console.log(foo.x);
console.log(foo);
console.log(obj);
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть простая таблица, нужно, чтобы при нажатии на поле, у него появлялась обвода и его можно было растянуть на другие поля (выше, ниже)
В таблице есть столбец с адресами формата: "город" + "улица и дом"Значения в таблицу попадают из json файла
В Yandex APi JS допустим когда сначала рисуешь один полигон затем рядом еще один полигон предусматривается автоматическое "cклеивание" границ...