Yang menarik tentang mereka adalah bahwa data bertahan dari penyegaran halaman (untuk alert( localStorage.getItem('test') ); // 15) dan bahkan browser sepenuhnya dimulai ulang (untuk alert( localStorage.getItem('test') ); // 14). Kita akan segera melihatnya
Kami sudah memiliki cookie. Mengapa objek tambahan?
- Tidak seperti cookie, objek penyimpanan web tidak dikirim ke server dengan setiap permintaan. Karena itu, kita dapat menyimpan lebih banyak. Sebagian besar browser modern mengizinkan setidaknya 5 megabyte data (atau lebih) dan memiliki pengaturan untuk mengonfigurasinya
- Juga tidak seperti cookie, server tidak dapat memanipulasi objek penyimpanan melalui header HTTP. Semuanya dilakukan dalam JavaScript
- Penyimpanan terikat ke asal (domain/protokol/port triplet). Artinya, protokol atau subdomain yang berbeda menyimpulkan objek penyimpanan yang berbeda, mereka tidak dapat mengakses data satu sama lain
Kedua objek penyimpanan menyediakan metode dan properti yang sama
- alert( localStorage.getItem('test') ); // 18 – menyimpan pasangan kunci/nilai
- alert( localStorage.getItem('test') ); // 1_9 – dapatkan nilai dengan kunci
- // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;_0 – hapus kunci dengan nilainya
- // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;_1 – hapus semuanya
- // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;_2 – mendapatkan kunci pada posisi tertentu
- // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;_3 – jumlah item yang disimpan
Seperti yang Anda lihat, ini seperti koleksi // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;4 (// set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;5), tetapi juga memungkinkan akses berdasarkan indeks dengan // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;2
Mari kita lihat cara kerjanya
Fitur utama dari alert( localStorage.getItem('test') ); // 1_4 adalah
- Dibagi antara semua tab dan jendela dari asal yang sama
- Data tidak kedaluwarsa. Tetap setelah browser restart dan bahkan reboot OS
Misalnya, jika Anda menjalankan kode ini…
localStorage.setItem('test', 1);
…Dan tutup/buka browser atau buka saja halaman yang sama di jendela yang berbeda, lalu Anda bisa mendapatkannya seperti ini
alert( localStorage.getItem('test') ); // 1
Kita hanya harus berada di Origin yang sama (domain/port/protocol), jalur urlnya bisa berbeda
alert( localStorage.getItem('test') ); // 14 dibagi antara semua jendela dengan asal yang sama, jadi jika kita mengatur data di satu jendela, perubahannya akan terlihat di jendela lain
Kita juga dapat menggunakan cara objek biasa untuk mendapatkan/mengatur kunci, seperti ini
// set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;_
Itu diperbolehkan karena alasan historis, dan sebagian besar berfungsi, tetapi umumnya tidak disarankan, karena
Jika kunci dibuat oleh pengguna, bisa apa saja, seperti // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test;3 atau let key = 'length'; localStorage[key] = 5; // Error, can't assign length0, atau metode bawaan lainnya dari alert( localStorage.getItem('test') ); // 14. Dalam hal itu let key = 'length'; localStorage[key] = 5; // Error, can't assign length_2 berfungsi dengan baik, sementara akses seperti objek gagal
let key = 'length'; localStorage[key] = 5; // Error, can't assign length
Ada peristiwa let key = 'length'; localStorage[key] = 5; // Error, can't assign length_3, yang dipicu saat kami mengubah data. Peristiwa itu tidak terjadi untuk akses seperti objek. Kita akan melihatnya nanti di bab ini
Seperti yang telah kita lihat, metode menyediakan fungsionalitas "dapatkan/setel/hapus dengan kunci". Tetapi bagaimana cara mendapatkan semua nilai atau kunci yang disimpan?
Sayangnya, objek penyimpanan tidak dapat diubah
Salah satu caranya adalah dengan mengulang mereka sebagai array
for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }
Cara lain adalah dengan menggunakan let key = 'length'; localStorage[key] = 5; // Error, can't assign length_4 loop, seperti yang kita lakukan dengan objek biasa
Itu berulang pada kunci, tetapi juga menampilkan beberapa bidang bawaan yang tidak kita perlukan
// bad try for(let key in localStorage) { alert(key); // shows getItem, setItem and other built-in stuff }
…Jadi kita perlu memfilter bidang dari prototipe dengan centang let key = 'length'; localStorage[key] = 5; // Error, can't assign length5
for(let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; // skip keys like "setItem", "getItem" etc } alert(`${key}: ${localStorage.getItem(key)}`); }
…Atau dapatkan saja kunci “milik sendiri” dengan let key = 'length'; localStorage[key] = 5; // Error, can't assign length6 lalu putar di atasnya jika diperlukan
let keys = Object.keys(localStorage); for(let key of keys) { alert(`${key}: ${localStorage.getItem(key)}`); }
Yang terakhir berfungsi, karena let key = 'length'; localStorage[key] = 5; // Error, can't assign length_6 hanya mengembalikan kunci milik objek, mengabaikan prototipe
Harap perhatikan bahwa kunci dan nilai harus berupa string
Jika mereka adalah tipe lain, seperti angka, atau objek, mereka akan dikonversi menjadi string secara otomatis
localStorage.user = {name: "John"}; alert(localStorage.user); // [object Object]
Kita bisa menggunakan let key = 'length'; localStorage[key] = 5; // Error, can't assign length_8 untuk menyimpan objek
localStorage.user = JSON.stringify({name: "John"}); // sometime later let user = JSON.parse( localStorage.user ); alert( user.name ); // John
Juga dimungkinkan untuk merangkai seluruh objek penyimpanan, mis. g. untuk tujuan debug
alert( localStorage.getItem('test') ); // 10
Objek alert( localStorage.getItem('test') ); // 15 lebih jarang digunakan daripada alert( localStorage.getItem('test') ); // 14
Properti dan metodenya sama, tetapi jauh lebih terbatas
- alert( localStorage.getItem('test') ); // 15 hanya ada dalam tab browser saat ini
- Tab lain dengan halaman yang sama akan memiliki penyimpanan yang berbeda
- Tapi itu dibagi antara iframe di tab yang sama (dengan asumsi mereka berasal dari asal yang sama)
- Data bertahan dari penyegaran halaman, tetapi tidak menutup/membuka tab
Mari kita lihat itu beraksi
Jalankan kode ini…
alert( localStorage.getItem('test') ); // 1_1
…Kemudian segarkan halaman. Sekarang Anda masih bisa mendapatkan datanya
alert( localStorage.getItem('test') ); // 1_2
…Tetapi jika Anda membuka halaman yang sama di tab lain, dan mencoba lagi di sana, kode di atas mengembalikan for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }2, artinya “tidak ada yang ditemukan”
Itu persis karena alert( localStorage.getItem('test') ); // 15 terikat tidak hanya pada asalnya, tetapi juga pada tab browser. Oleh karena itu, alert( localStorage.getItem('test') ); // 15 digunakan dengan hemat
Saat data diperbarui di alert( localStorage.getItem('test') ); // 1_4 atau alert( localStorage.getItem('test') ); // 15, pemicu peristiwa, dengan properti
- for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }_7 – kunci yang diubah (for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }2 jika for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }9 dipanggil)
- // bad try for(let key in localStorage) { alert(key); // shows getItem, setItem and other built-in stuff }0 – nilai lama (for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }2 jika kunci baru ditambahkan)
- // bad try for(let key in localStorage) { alert(key); // shows getItem, setItem and other built-in stuff }2 – nilai baru (for(let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); alert(`${key}: ${localStorage.getItem(key)}`); }2 jika kunci dihapus)
- // bad try for(let key in localStorage) { alert(key); // shows getItem, setItem and other built-in stuff }4 – url dokumen tempat pembaruan terjadi
- // bad try for(let key in localStorage) { alert(key); // shows getItem, setItem and other built-in stuff }5 – objek alert( localStorage.getItem('test') ); // 14 atau alert( localStorage.getItem('test') ); // 15 tempat pembaruan terjadi
Yang penting adalah. peristiwa dipicu pada semua // bad try for(let key in localStorage) { alert(key); // shows getItem, setItem and other built-in stuff }_8 objek tempat penyimpanan dapat diakses, kecuali yang menyebabkannya
Mari kita uraikan
Bayangkan, Anda memiliki dua jendela dengan situs yang sama di masing-masingnya. Jadi alert( localStorage.getItem('test') ); // 1_4 dibagi di antara mereka
Anda mungkin ingin membuka halaman ini di dua jendela browser untuk menguji kode di bawah ini
Jika kedua jendela mendengarkan for(let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; // skip keys like "setItem", "getItem" etc } alert(`${key}: ${localStorage.getItem(key)}`); }_0, maka masing-masing jendela akan bereaksi terhadap pembaruan yang terjadi di jendela lainnya
alert( localStorage.getItem('test') ); // 1_3
Harap dicatat bahwa acara tersebut juga berisi. for(let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; // skip keys like "setItem", "getItem" etc } alert(`${key}: ${localStorage.getItem(key)}`); }1 – url dokumen tempat data diperbarui
Selain itu, for(let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; // skip keys like "setItem", "getItem" etc } alert(`${key}: ${localStorage.getItem(key)}`); }_2 berisi objek penyimpanan – kejadiannya sama untuk alert( localStorage.getItem('test') ); // 15 dan alert( localStorage.getItem('test') ); // 14, jadi for(let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; // skip keys like "setItem", "getItem" etc } alert(`${key}: ${localStorage.getItem(key)}`); }2 mereferensikan yang telah dimodifikasi. Kita bahkan mungkin ingin mengembalikan sesuatu ke dalamnya, untuk “merespons” suatu perubahan
Itu memungkinkan jendela berbeda dari asal yang sama untuk bertukar pesan
Browser modern juga mendukung Broadcast channel API, API khusus untuk komunikasi antar-jendela asal yang sama, fiturnya lebih lengkap, tetapi kurang didukung. Ada perpustakaan yang mengisi ulang API tersebut, berdasarkan alert( localStorage.getItem('test') ); // 14, yang membuatnya tersedia di mana saja