Важливо розуміти, що =робить і чого не робить оператор у JavaScript.
=Оператор не робить копію даних.
=Оператор створює нову посилання на той же дані.
Після запуску оригінального коду:
var a = $('#some_hidden_var').val(),
b = a;
aі bтепер це дві різні назви для одного і того ж об’єкта .
Будь-які зміни, які ви внесете до вмісту цього об'єкта, будуть сприйматися однаково, незалежно від того, посилаєтесь ви на нього через aзмінну чи bзмінну. Вони один і той же об’єкт.
Отже, коли ви пізніше спробуєте "повернутися" bдо початкового aоб'єкта за допомогою цього коду:
b = a;
Код насправді взагалі нічого не робить , тому що aі bє абсолютно однаковим. Код такий самий, як якщо б ви написали:
b = b;
яка, очевидно, нічого не зробить.
Чому ваш новий код працює?
b = { key1: a.key1, key2: a.key2 };
Тут ви створюєте абсолютно новий об’єкт з {...}літералом об’єкта. Цей новий об’єкт не такий, як ваш старий об’єкт. Отже, ви зараз встановлюєте bяк посилання на цей новий об’єкт, який робить те, що ви хочете.
Для обробки будь-якого довільного об'єкта ви можете використовувати функцію клонування об'єкта, таку як перелічена у відповіді Армана, або оскільки ви використовуєте jQuery, просто використовуйте $.extend()функцію . Ця функція робить або поверхневу копію, або глибоку копію об'єкта. (Не плутайте це з $().clone()методом копіювання елементів DOM, а не об'єктів.)
Для дрібної копії:
b = $.extend( {}, a );
Або глибока копія:
b = $.extend( true, {}, a );
Яка різниця між неглибокою копією та глибокою копією? Неглибока копія схожа на ваш код, який створює новий об'єкт із літералом об'єкта. Він створює новий об'єкт верхнього рівня, що містить посилання на ті самі властивості, що і вихідний об'єкт.
Якщо ваш об'єкт містить лише примітивні типи, такі як числа та рядки, глибока копія та неглибока копія робитимуть точно те саме. Але якщо ваш об'єкт містить інші вкладені в нього об'єкти або масиви, тоді неглибока копія не копіює ці вкладені об'єкти, вона просто створює посилання на них. Отже, у вас може бути та сама проблема із вкладеними об’єктами, що і у вашого об’єкта верхнього рівня. Наприклад, враховуючи цей об'єкт:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
Якщо ви робите неглибоку копію цього об’єкта, то xвластивістю вашого нового об’єкта є той самий xоб’єкт з оригіналу:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
Тепер ваші об'єкти будуть виглядати так:
// copy looks as expected
var copy = {
w: 321,
x: {
y: 654,
z: 789
}
};
// But changing copy.x.y also changed obj.x.y!
var obj = {
w: 123, // changing copy.w didn't affect obj.w
x: {
y: 654, // changing copy.x.y also changed obj.x.y
z: 789
}
};
Цього можна уникнути за допомогою глибокої копії. Глибока копія повторюється в кожен вкладений об'єкт і масив (і Дата в коді Арманда), щоб зробити копії цих об'єктів так само, як і копію об'єкта верхнього рівня. Тож зміна copy.x.yне вплине obj.x.y.
Коротка відповідь: Якщо ви сумніваєтесь, ви, мабуть, хочете глибоку копію.
aбуло встановлено з,.val()я припускаю, що це JSON (рядок), а не об'єкт - це правильно? Чи використовуєте виJSON.parse(a)в якийсь момент для отримання фактичного об'єкта?