Saya memiliki variabel yang memiliki objek JSON sebagai nilainya. Saya langsung menetapkan variabel ini ke beberapa variabel lain sehingga mereka memiliki nilai yang sama. Begini Cara kerjanya:
var a = $('#some_hidden_var').val(),
b = a;
Ini berfungsi dan keduanya memiliki nilai yang sama. Saya menggunakan mousemove
event handler untuk mengupdate b
seluruh aplikasi saya. Pada satu klik tombol, saya ingin kembali b
ke nilai asli, artinya nilai yang disimpan a
.
$('#revert').on('click', function(e){
b = a;
});
Setelah ini, jika saya menggunakan mousemove
event handler yang sama , ia memperbarui keduanya a
dan b
, ketika sebelumnya hanya memperbarui b
seperti yang diharapkan.
Saya bingung tentang masalah ini! Ada apa disini?
javascript
jquery
Rutwick Gangurde
sumber
sumber
a
ditetapkan dari.val()
saya menganggap itu adalah JSON (string), bukan objek - apakah itu benar? Apakah Anda menggunakanJSON.parse(a)
suatu saat untuk mendapatkan objek yang sebenarnya?$.parseJSON
untuk mengubahnya menjadi objek. Struktur:{ 'key': {...}, 'key': {...}, ...}
. Maaf tidak dapat memposting kode apa pun di sini, tidak diizinkan di tempat kerja saya!a
sebuah objek?a
variabel global?$.parseJSON()
?) Sulit untuk mengatakan apa masalahnya. Mengenai aturan tempat kerja Anda, Anda tidak perlu memposting kode asli Anda secara lengkap, cukup buat contoh yang lebih pendek dan lebih umum yang menunjukkan masalah tersebut (dan, idealnya, sertakan tautan ke demo langsung di jsfiddle.net ) .Jawaban:
Penting untuk memahami apa yang
=
dilakukan dan tidak dilakukan oleh operator di JavaScript.The
=
operator tidak membuat salinan data.The
=
Operator menciptakan baru referensi ke yang sama data.Setelah Anda menjalankan kode asli Anda:
a
danb
sekarang ada dua nama berbeda untuk objek yang sama .Setiap perubahan yang Anda lakukan pada konten objek ini akan terlihat sama, baik Anda mereferensikannya melalui
a
variabel ataub
variabel. Mereka adalah objek yang sama.Jadi, ketika Anda nanti mencoba untuk "kembali"
b
kea
objek asli dengan kode ini:Kode sebenarnya tidak melakukan apa - apa , karena
a
danb
merupakan hal yang persis sama. Kode tersebut sama seperti jika Anda menulis:yang jelas tidak akan melakukan apapun.
Mengapa kode baru Anda berfungsi?
Di sini Anda membuat objek baru dengan
{...}
literal objek. Objek baru ini tidak sama dengan objek lama Anda. Jadi Anda sekarang menyetelb
sebagai referensi ke objek baru ini, yang melakukan apa yang Anda inginkan.Untuk menangani objek arbitrer, Anda dapat menggunakan fungsi kloning objek seperti yang tercantum dalam jawaban Armand, atau karena Anda menggunakan jQuery, cukup gunakan
$.extend()
fungsi tersebut . Fungsi ini akan membuat salinan dangkal atau salinan dalam dari suatu objek. (Jangan bingung ini dengan$().clone()
metode untuk menyalin elemen DOM, bukan objek.)Untuk salinan dangkal:
Atau salinan dalam:
Apa perbedaan antara salinan dangkal dan salinan dalam? Salinan dangkal mirip dengan kode Anda yang membuat objek baru dengan literal objek. Ini membuat objek tingkat atas baru yang berisi referensi ke properti yang sama seperti objek aslinya.
Jika objek Anda hanya berisi tipe primitif seperti angka dan string, salinan dalam dan salinan dangkal akan melakukan hal yang persis sama. Tetapi jika objek Anda berisi objek atau larik lain yang bersarang di dalamnya, salinan dangkal tidak akan menyalin objek bertingkat itu, itu hanya membuat referensi ke sana. Jadi, Anda bisa memiliki masalah yang sama dengan objek bersarang yang Anda miliki dengan objek level teratas. Misalnya, diberikan objek ini:
Jika Anda melakukan penyalinan dangkal dari objek tersebut, maka
x
properti objek baru Anda adalah objek yang samax
dari aslinya:Sekarang objek Anda akan terlihat seperti ini:
Anda dapat menghindari ini dengan salinan dalam. Salinan dalam berulang ke dalam setiap objek dan larik bersarang (dan Tanggal dalam kode Armand) untuk membuat salinan objek tersebut dengan cara yang sama seperti membuat salinan objek tingkat atas. Jadi, perubahan
copy.x.y
tidak akan berpengaruhobj.x.y
.Jawaban singkat: Jika ragu, Anda mungkin menginginkan salinan yang mendalam.
sumber
$.extend()
fungsi bawaan. Detail di atas. :-)Saya menemukan menggunakan JSON berfungsi tetapi perhatikan referensi melingkar kami
sumber
let a = {}; let b = {a:a}; a.b = b; JSON.stringify(a)
akan memberikan TypeErrorpertanyaannya sudah terpecahkan sejak waktu yang cukup lama, tetapi untuk referensi di masa mendatang solusi yang mungkin adalah
Hati-hati, ini berfungsi dengan benar hanya jika a adalah larik angka dan string yang tidak bersarang
sumber
newVariable = originalVariable.valueOf();
untuk objek yang dapat Anda gunakan,
b = Object.assign({},a);
sumber
Alasannya sederhana. JavaScript menggunakan referensi, jadi ketika Anda menetapkan
b = a
Anda menetapkan referensib
sehingga saat memperbaruia
Anda juga memperbaruib
Saya menemukan ini di stackoverflow dan akan membantu mencegah hal-hal seperti ini di masa mendatang hanya dengan memanggil metode ini jika Anda ingin melakukan salinan mendalam dari suatu objek.
sumber
if (obj instanceof x) { ... }
harus menjadi yang lain?Saya tidak mengerti mengapa jawabannya begitu rumit. Dalam Javascript, primitif (string, angka, dll) diteruskan oleh nilai, dan disalin. Objek, termasuk array, diteruskan dengan referensi. Bagaimanapun, penugasan nilai baru atau referensi objek ke 'a' tidak akan mengubah 'b'. Tetapi mengubah konten 'a' akan mengubah konten 'b'.
Tempel salah satu baris di atas (satu per satu) ke dalam node atau konsol javascript browser apa pun. Kemudian ketik variabel apa saja dan konsol akan menunjukkan nilainya.
sumber
Untuk string atau nilai input Anda cukup menggunakan ini:
sumber
Sebagian besar jawaban di sini menggunakan metode bawaan atau menggunakan perpustakaan / kerangka kerja. Metode sederhana ini seharusnya berfungsi dengan baik:
sumber
Object.assign({},a)
Saya menyelesaikannya sendiri untuk saat ini. Nilai asli hanya memiliki 2 sub-properti. Saya mereformasi objek baru dengan properti dari
a
dan kemudian menugaskannyab
. Sekarang event handler saya hanya memperbaruib
, dan yang aslia
tetap seperti itu.Ini bekerja dengan baik. Saya belum mengubah satu baris pun di kode saya kecuali yang di atas, dan berfungsi seperti yang saya inginkan. Jadi, percayalah, tidak ada lagi yang memperbarui
a
.sumber
Solusi untuk AngularJS :
sumber