Может кто-нибудь объяснить мне это поведение javascript объекта "копировать" - PullRequest
7 голосов
/ 06 июля 2011

У меня есть следующий код (я использую библиотеку jQquery):

var obj = {};
var objstring = '{"one":"one","two":"two","three":"three"}'

// first console output
console.log(objstring);

var jsonobj = $.parseJSON(objstring);

// second console output
console.log(jsonobj);

obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";

// third console output
console.log(jsonobj);

Мой вопрос: Когда я делаю obj.key = jsonobj и я изменяю значения в новом obj.key. Почему значения в jsonobj также меняются? И как бы мне этого избежать? (Я хочу новую «копию» jsonobj).

Я сделал этот контрольный пример: http://jsfiddle.net/WSgVz/

Ответы [ 5 ]

5 голосов
/ 06 июля 2011

Я хочу затронуть небольшую часть того, что здесь происходит, поскольку другие хорошо справились с более крупными проблемами ссылок на объекты JavaScript:

// second console output
console.log(jsonobj);

obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";

Это результат задокументированная ошибка WebKit , что операторы console.log не выводят объект во время вызова console.log, а вместо этого через некоторое время.

3 голосов
/ 06 июля 2011

Это потому, что объект не скопирован. Свойство obj.key будет содержать только ссылку на объект, поэтому при назначении чего-либо на obj.key.test эффект аналогичен назначению его на jsonobj.test.

Вы можете использовать метод jQuery extension для создания копии:

obj.key = $.extend({}, jsonobj);

Это скопирует значения во вновь созданный объект ({}).

2 голосов
/ 06 июля 2011

Потому что когда вы делаете obj.key = jsonobj, в obj.key не появляется какой-либо новый скопированный объект;это просто ссылка на jsonobj, который уже существует.Поэтому изменения в obj.key также изменят jsonobj, потому что на самом деле это одно и то же.

1 голос
/ 06 июля 2011

Все объекты в JavaScript копируются по ссылке, что означает:

var x = {};
var y = x;
x.foo = 22; // y.foo also = 22 since y and x are the same object

Если вы хотите obj.key != jsonobj, вам нужно клонировать объект. Создавая новый объект:

obj.key = $.parseJSON(objstring);

или использование jQuery для клонирования существующего:

obj.key = $.extend({}, jsonobj);
1 голос
/ 06 июля 2011

Это потому, что означает, что копирование не выполняется - есть только один объект, на который ссылаются на различные переменные и свойства. Когда вы делаете obj.key = jsonobj, вы просто копируете ссылку на тот же объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...