Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Изменяется родительский массив (https://javascript.ru/forum/misc/52505-izmenyaetsya-roditelskijj-massiv.html)

voodoo_dn 22.12.2014 14:44

Изменяется родительский массив
 
Добрый день!

У меня есть массив settings.users с исходными данными.
В необходимой функции я делаю:
users = settings.users;

Далее идёт поиск, замена значений в users. Но все данные так же меняются в settings.users. Как это исправить? методы array.push не подходят.

MallSerg 22.12.2014 14:54

http://web.izjum.com/javascript-copy...comment-page-1

Потому что в JS по значению копируются только примитивные типы
Сложные копируются по ссылке т.е. "=" не создаёт в памяти копию объекта а просто берет ссылку на уже существующий объект.

Vlasenko Fedor 22.12.2014 14:56

а ты его клонируй, к примеру так
users = settings.users.slice(0);

:)

Aetae 22.12.2014 15:50

...только если там есть подмассивы то их тоже надо отдельно клонировать.)

voodoo_dn 22.12.2014 17:08

У меня массив объектов. Пол дня бьюсь в поисках решения =/

jsnb 22.12.2014 17:19

Если нет циклических ссылок, то можно сделать так:
users = JSON.parse( JSON.stringify(settings.users) );

krutoy 22.12.2014 18:20

Цитата:

Сообщение от MallSerg
Потому что в JS по значению копируются только примитивные типы

a="foo"
b=a
alert(a===b)
// true

ничего там не копируется. а и b указывают на один и тот же объект.
Цитата:

Сообщение от jsnb
Если нет циклических ссылок

Что значит циклические ссылки?

jsnb 22.12.2014 18:41

Цитата:

Сообщение от krutoy
Что значит циклические ссылки?

var obj1 = {}, obj2 = {};
obj1.aaa = obj2; 
obj2.bbb = obj1;
try {
  JSON.stringify(obj1);
} catch(e) {
  alert(e);
}

tsigel 22.12.2014 18:44

Цитата:

Сообщение от krutoy (Сообщение 347700)
a="foo"
b=a
alert(a===b)
// true

ничего там не копируется. а и b указывают на один и тот же объект.
Что значит циклические ссылки?

a="foo"
b=a
alert(a===b)
// true
a = "fppp";
console.log(b);
//foo

В данном случае они не
Цитата:

Сообщение от krutoy (Сообщение 347700)
указывают на один и тот же объект

, а сравниваются по значению, потому что это не объекты а строки.

krutoy 22.12.2014 18:53

tsigel,
Ничего там у Вас не копируется. a вначале указывала на foo, а после присваивания стала указывать на fppp, только и всего.

krutoy 22.12.2014 19:11

jsnb,
А, ну это обычные циклические ссылки, я думал, Вы что-то другое имеете в виду. Только, я не пойму, что мешает этому JSON.stringify преобразовать в строку такой объект? Почему он ругается?

Aetae 22.12.2014 19:15

krutoy, потому что форматом json это не предусмотрено. Сам попробуй преобразовать в ручную в валидный json такой объект.
В строку кода - можно, но это совсем другое, ибо json придуман в том числе и для взаимодействия с иными языками.

MallSerg 22.12.2014 20:07

Цитата:

Сообщение от krutoy
tsigel,
Ничего там у Вас не копируется. a вначале указывала на foo, а после присваивания стала указывать на fppp, только и всего.

Добавим капельку непонятной магии =)
a1 = "Привет";
b1 = "Привет";

a2 = new String ("Привет");
b2 = new String ("Привет");

alert ( " a1 === b1 " + ( a1 === b1) );
alert ( " a2 === b2 " + ( a2 === b2) );

krutoy 22.12.2014 20:19

MallSerg,
Вы сравниваете во втором случае не примитивные данные, а объекты. Не вижу никакой магии, и, тем более, связи с сабжем. Все работает как ожидается. Легко проверить
a2 = new String ("Привет");
b2 = new String ("Привет");
 
alert ( " a2 === b2 " + ( a2.valueOf() === b2.valueOf()) );
//   a2 === b2 true

MallSerg 22.12.2014 20:29

А переменные

a1 = "Привет";
b1 = "Привет";

все также указывают на одну и туже строку?
Просто цель данного примера была наглядно показать
как работает строгое сравнение для примитивных строк
и как для объектов показать что поведение разное т.е. приводит к разным результатам
это основы языка.

krutoy 22.12.2014 20:45

Цитата:

Сообщение от MallSerg
все также указывают на одну и туже строку?

да, а почему должно было что-то измениться?

krutoy 22.12.2014 20:53

Цитата:

Сообщение от MallSerg
строгое сравнение

Строгое сравнение работает очень просто. Если оба имени указывают в одно и то же место, оно возвращает истину. Больше никаких правил нет. И никакого отношения к вопросу о копировании это не имеет.

MallSerg 22.12.2014 21:19

Тогда срочно отпровляй письмо в w3c что у них ошибка с стандарте EMAScript
И попроси Илью исправить учебник http://javascript.ru/comparison-operators

krutoy 22.12.2014 21:25

MallSerg,
погляди в окно, не я там бегу стандарты менять?


Часовой пояс GMT +3, время: 14:01.