26 Pertanyaan: Menyimpan Objek di HTML5 localStorage

pertanyaan dibuat di Wed, May 17, 2017 12:00 AM

Saya ingin menyimpan objek JavaScript dalam HTML5 localStorage, tetapi objek saya tampaknya sedang dikonversi ke string.

Saya dapat menyimpan dan mengambil jenis dan array JavaScript primitif menggunakan localStorage, tetapi objek sepertinya tidak berfungsi. Haruskah mereka

Ini kode saya:

 
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
console.log('typeof testObject: ' + typeof testObject);
console.log('testObject properties:');
for (var prop in testObject) {
    console.log('  ' + prop + ': ' + testObject[prop]);
}

// Put the object into storage
localStorage.setItem('testObject', testObject);

// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');

console.log('typeof retrievedObject: ' + typeof retrievedObject);
console.log('Value of retrievedObject: ' + retrievedObject);

Output konsolnya adalah

 
typeof testObject: object
testObject properties:
  one: 1
  two: 2
  three: 3
typeof retrievedObject: string
Value of retrievedObject: [object Object]

Bagi saya sepertinya metode setItem mengonversi input ke string sebelum menyimpannya.

Saya melihat perilaku ini di Safari, Chrome, dan Firefox, jadi saya menganggap ini adalah kesalahpahaman saya tentang HTML5 Spesifikasi Penyimpanan Web , bukan bug atau batasan khusus browser.

Saya sudah mencoba memahami algoritma klon terstruktur yang dijelaskan dalam http://www.w3.org/TR/html5/infrastructure.html . Saya tidak sepenuhnya mengerti apa yang dikatakannya, tapi mungkin masalah saya ada hubungannya dengan properti objek saya yang tidak dapat dihitung (???)

Apakah ada solusi yang mudah?


Pembaruan: W3C akhirnya berubah pikiran tentang spesifikasi klon terstruktur, dan memutuskan untuk mengubah spesifikasi agar sesuai dengan implementasi. Lihat https://www.w3.org/Bugs/Public/show_bug. cgi? id = 12111 . Jadi pertanyaan ini tidak lagi 100% valid, tetapi jawabannya mungkin masih menarik.

    
2294
  1. BTW, bacaan Anda tentang "algoritma kloning terstruktur" benar, hanya saja speknya diubah dari nilai string-only menjadi ini setelah implementasinya keluar. Saya mengajukan bug bugzilla.mozilla.org/show_bug.cgi?id=538142 dengan mozilla untuk melacak masalah ini.
    2010-01-06 13: 30: 05Z
  2. Ini sepertinya pekerjaan untuk indexedDB ...
    2013-08-02 02: 06: 09Z
  3. Bagaimana kalau menyimpan array Object di localStorage? Saya menghadapi masalah yang sama dengan konversi ke string.
    2017-06-09 19: 08: 26Z
  4. dapatkah Anda hanya membuat serialisasi array? seperti toko dengan JSON yang dirangkaikan kemudian diurai lagi saat memuat?
    2018-03-12 06: 35: 24Z
  5. Anda dapat menggunakan localDataStorage untuk secara transparan menyimpan tipe data javascript ( Array, Boolean, Date, Float, Integer, String dan Object)
    2018-06-11 00: 54: 45Z
26 Jawaban                              26                         

Melihat Apple , Mozilla dan Mozilla again dokumentasi, fungsionalitas tampaknya terbatas untuk hanya menangani kunci /nilai string. pasangan.

Solusinya adalah dengan stringify objek Anda sebelum menyimpannya, dan kemudian menguraikannya saat Anda mengambilnya:

 
var testObject = { 'one': 1, 'two': 2, 'three': 3 };

// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));

// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');

console.log('retrievedObject: ', JSON.parse(retrievedObject));
    
2914
2019-06-15 04: 06: 54Z
  1. amati bahwa setiap metadata akan dihapus. Anda baru saja mendapatkan objek dengan pasangan nilai kunci, sehingga objek apa pun yang berperilaku perlu dibangun kembali.
    2013-10-07 18: 48: 42Z
  2. @ CMS dapat mengaturItem melemparkan beberapa pengecualian jika data melebihi kapasitas?
    2014-03-26 09: 27: 36Z
  3. ... berlaku untuk objek hanya dengan referensi melingkar, JSON.stringify() memperluas objek yang direferensikan ke "konten" penuhnya (tersurat tersirat) pada objek yang kami tegaskan. Lihat: stackoverflow.com/a/12659424/2044940
    2014-07-23 16: 54: 51Z
  4. Masalah dengan pendekatan ini adalah masalah kinerja, jika Anda harus menangani array atau objek besar.
    2014-10-29 09: 35: 28Z
  5. @ oligofren true, tetapi sebagai maja yang disarankan dengan benar eval () = > , ini adalah salah satu gunanya, Anda dapat dengan mudah mengambil kode fungsi = > simpan sebagai string dan kemudian eval () kembali :)
    2015-07-06 20: 03: 52Z

Perbaikan kecil pada varian :

 
Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

Karena evaluasi sirkuit pendek , getObject() akan segera kembalikan null jika key tidak ada dalam Storage. Ini juga tidak akan membuang pengecualian SyntaxError jika value adalah "" (string kosong; JSON.parse() tidak dapat mengatasinya).

    
595
2018-04-28 19: 40: 05Z
  1. Saya hanya ingin dengan cepat menambahkan penggunaan karena tidak segera jelas bagi saya: var userObject = { userId: 24, name: 'Jack Bauer' }; Dan untuk mengaturnya localStorage.setObject('user', userObject); Kemudian dapatkan kembali dari penyimpanan userObject = localStorage.getObject('user'); Anda bahkan dapat menyimpan sebuah array objek jika Anda inginkan.
    2011-08-16 21: 38: 07Z
  2. Itu hanya ekspresi boolean. Bagian kedua dievaluasi hanya jika yang kiri benar. Dalam hal ini hasil dari seluruh ekspresi akan berasal dari bagian yang benar. Ini adalah teknik populer berdasarkan cara bagaimana ekspresi boolean dievaluasi.
    2011-11-01 21: 04: 19Z
  3. Saya tidak melihat titik variabel lokal dan evaluasi pintasan di sini (perbaikan kinerja kecil). Jika key tidak ada di Penyimpanan Lokal, window.localStorage.getItem(key) mengembalikan null - tidak tidak melempar pengecualian "Akses ilegal" - dan JSON.parse(null) mengembalikan null juga - ia tidak melempar pengecualian, baik di Chromium 21 atau per ES 5.1 bagian 15.12.2 , karena String(null) === "null" yang dapat diartikan sebagai JSON literal .
    2012-10-08 10: 20: 17Z
  4. Nilai dalam Penyimpanan Lokal selalu merupakan nilai string primitif. Jadi yang ditangani evaluasi jalan pintas ini adalah ketika seseorang menyimpan "" (string kosong) sebelumnya. Karena itu ketik-convert ke false dan JSON.parse(""), yang akan membuang pengecualian SyntaxError, tidak disebut.
    2012-10-08 10: 42: 24Z
  5. Ini tidak akan berfungsi di IE8, jadi Anda lebih baik menggunakan fungsi di jawaban yang dikonfirmasi jika Anda perlu mendukungnya.
    2013-01-16 12: 15: 23Z

Anda mungkin perlu memperluas objek Penyimpanan dengan metode praktis berikut:

 
Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    return JSON.parse(this.getItem(key));
}

Dengan cara ini Anda mendapatkan fungsionalitas yang benar-benar Anda inginkan meskipun di bawah API hanya mendukung string.

    
206
2010-01-06 04: 42: 47Z
  1. Membungkus pendekatan CMS ke dalam sebuah fungsi adalah ide yang bagus, itu hanya memerlukan tes fitur: Satu untuk JSON.stringify, satu untuk JSON.parse, dan satu untuk menguji apakah localStorage sebenarnya dapat mengatur dan mengambil objek. Memodifikasi objek host bukanlah ide yang baik; Saya lebih suka melihat ini sebagai metode terpisah dan bukan sebagai localStorage.setObject.
    2010-12-09 01: 28: 14Z
  2. getObject() ini akan mengeluarkan pengecualian SyntaxError jika nilai yang disimpan adalah "", karena JSON.parse() tidak bisa mengatasinya. Lihat edit saya untuk jawaban Guria untuk detailnya.
    2012-10-08 10: 45: 56Z
  3. Hanya dua sen saya, tapi saya cukup yakin itu bukan ide yang baik untuk memperluas objek yang disediakan oleh vendor seperti ini.
    2014-07-06 18: 54: 40Z

Memperluas objek Penyimpanan adalah solusi yang luar biasa. Untuk API saya, saya telah membuat fasad untuk localStorage dan kemudian memeriksa apakah itu objek atau tidak saat mengatur dan mendapatkan.

 
var data = {
  set: function(key, value) {
    if (!key || !value) {return;}

    if (typeof value === "object") {
      value = JSON.stringify(value);
    }
    localStorage.setItem(key, value);
  },
  get: function(key) {
    var value = localStorage.getItem(key);

    if (!value) {return;}

    // assume it is an object that has been stringified
    if (value[0] === "{") {
      value = JSON.parse(value);
    }

    return value;
  }
}
    
68
2013-10-25 16: 32: 44Z
  1. Ini hampir persis seperti yang saya butuhkan. Baru saja menambahkan jika (nilai == null) {return false} sebelum komentar, jika tidak menghasilkan kesalahan saat memeriksa keberadaan kunci pada localStorage.
    2012-03-08 20: 09: 48Z
  2. Ini sebenarnya cukup keren. Setuju dengan @FrancescoFrapporti Anda perlu jika di sana untuk nilai nol. Saya juga menambahkan '|| nilai [0] == "[" 'tes kalau-kalau ada dalam array di sana.
    2012-03-13 00: 06: 59Z
  3. Poin bagus, saya akan mengedit ini. Meskipun Anda tidak memerlukan bagian nol, tetapi jika Anda melakukannya saya sarankan tiga ===. Jika Anda menggunakan JSHint atau JSLint, Anda akan diperingatkan untuk tidak menggunakan ==.
    2012-11-02 15: 15: 19Z
  4. Dan untuk non-ninja (seperti saya), dapatkah seseorang memberikan contoh penggunaan untuk jawaban ini? Apakah itu: data.set('username': 'ifedi', 'fullname': { firstname: 'Ifedi', lastname: 'Okonkwo'});?
    2015-06-20 08: 13: 34Z
  5. Ya memang! Ketika saya mengatasi keinginan saya untuk diberi makan sendok, saya mengambil kode untuk diuji, dan mendapatkannya. Saya pikir jawaban ini hebat karena 1) Tidak seperti jawaban yang diterima, butuh waktu untuk melakukan pemeriksaan tertentu pada data string, dan 2) Tidak seperti yang berikutnya, ia tidak memperluas objek asli.
    2015-06-20 08: 27: 38Z

    Stringify tidak menyelesaikan semua masalah

    Tampaknya jawaban di sini tidak mencakup semua jenis yang dimungkinkan dalam JavaScript, jadi inilah beberapa contoh singkat tentang cara menanganinya dengan benar:

     
    //Objects and Arrays:
        var obj = {key: "value"};
        localStorage.object = JSON.stringify(obj);  //Will ignore private members
        obj = JSON.parse(localStorage.object);
    //Boolean:
        var bool = false;
        localStorage.bool = bool;
        bool = (localStorage.bool === "true");
    //Numbers:
        var num = 42;
        localStorage.num = num;
        num = +localStorage.num;    //short for "num = parseFloat(localStorage.num);"
    //Dates:
        var date = Date.now();
        localStorage.date = date;
        date = new Date(parseInt(localStorage.date));
    //Regular expressions:
        var regex = /^No\.[\d]*$/i;     //usage example: "No.42".match(regex);
        localStorage.regex = regex;
        var components = localStorage.regex.match("^/(.*)/([a-z]*)$");
        regex = new RegExp(components[1], components[2]);
    //Functions (not recommended):
        function func(){}
        localStorage.func = func;
        eval( localStorage.func );      //recreates the function with the name "func"
    

    Saya tidak merekomendasikan untuk menyimpan fungsi karena eval() jahat dapat menyebabkan masalah terkait keamanan, pengoptimalan, dan debugging.         Secara umum, eval() tidak boleh digunakan dalam kode JavaScript.

    Anggota pribadi

    Masalah dengan menggunakan JSON.stringify() untuk menyimpan objek adalah, bahwa fungsi ini tidak dapat membuat serial anggota pribadi. Masalah ini dapat diselesaikan dengan menimpa metode .toString() (yang disebut secara implisit saat menyimpan data di penyimpanan web):

     
    //Object with private and public members:
        function MyClass(privateContent, publicContent){
            var privateMember = privateContent || "defaultPrivateValue";
            this.publicMember = publicContent  || "defaultPublicValue";
    
            this.toString = function(){
                return '{"private": "' + privateMember + '", "public": "' + this.publicMember + '"}';
            };
        }
        MyClass.fromString = function(serialisedString){
            var properties = JSON.parse(serialisedString || "{}");
            return new MyClass( properties.private, properties.public );
        };
    //Storing:
        var obj = new MyClass("invisible", "visible");
        localStorage.object = obj;
    //Loading:
        obj = MyClass.fromString(localStorage.object);
    

    Referensi melingkar

    Masalah lain yang tidak dapat ditangani stringify adalah referensi melingkar:

     
    var obj = {};
    obj["circular"] = obj;
    localStorage.object = JSON.stringify(obj);  //Fails
    

    Dalam contoh ini, JSON.stringify() akan melempar TypeError "Mengubah struktur lingkaran menjadi JSON" .         Jika menyimpan referensi melingkar harus didukung, parameter kedua JSON.stringify() mungkin digunakan:

     
    var obj = {id: 1, sub: {}};
    obj.sub["circular"] = obj;
    localStorage.object = JSON.stringify( obj, function( key, value) {
        if( key == 'circular') {
            return "$ref"+value.id+"$";
        } else {
            return value;
        }
    });
    

    Namun, menemukan solusi yang efisien untuk menyimpan referensi melingkar sangat depberakhir pada tugas yang perlu diselesaikan, dan mengembalikan data tersebut juga tidak sepele.

    Sudah ada beberapa pertanyaan tentang SO dalam menangani masalah ini: Stringify (konversikan ke JSON) objek JavaScript dengan referensi melingkar

        
    59
    2017-05-23 12: 02: 49Z

    Ada perpustakaan hebat yang membungkus banyak solusi sehingga bahkan mendukung browser lama yang disebut jStorage

    Anda dapat mengatur objek

     
    $.jStorage.set(key, value)
    

    Dan mengambilnya dengan mudah

     
    value = $.jStorage.get(key)
    value = $.jStorage.get(key, "default value")
    
        
    51
    2018-03-27 03: 14: 53Z
    1. $adalah ilegal !!!
      2016-08-30 00: 57: 28Z
    2. @ SuperUberDuper jStorage membutuhkan Prototipe, MooTools, atau jQuery
      2016-08-30 23: 02: 32Z

    Menggunakan objek JSON untuk penyimpanan lokal:

    //SET

     
    var m={name:'Hero',Title:'developer'};
    localStorage.setItem('us', JSON.stringify(m));
    

    //DAPATKAN

     
    var gm =JSON.parse(localStorage.getItem('us'));
    console.log(gm.name);
    

    //Iterasi semua kunci dan nilai penyimpanan lokal

     
    for (var i = 0, len = localStorage.length; i < len; ++i) {
      console.log(localStorage.getItem(localStorage.key(i)));
    }
    

    //HAPUS

     
    localStorage.removeItem('us');
    delete window.localStorage["us"];
    
        
    33
    2017-02-17 15: 09: 15Z

    Secara teori, dimungkinkan untuk menyimpan objek dengan fungsi:

     
    function store (a)
    {
      var c = {f: {}, d: {}};
      for (var k in a)
      {
        if (a.hasOwnProperty(k) && typeof a[k] === 'function')
        {
          c.f[k] = encodeURIComponent(a[k]);
        }
      }
    
      c.d = a;
      var data = JSON.stringify(c);
      window.localStorage.setItem('CODE', data);
    }
    
    function restore ()
    {
      var data = window.localStorage.getItem('CODE');
      data = JSON.parse(data);
      var b = data.d;
    
      for (var k in data.f)
      {
        if (data.f.hasOwnProperty(k))
        {
          b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")");
        }
      }
    
      return b;
    }
    

    Namun, serialisasi /deserialisasi fungsi tidak dapat diandalkan karena itu tergantung pada implementasi .

        
    27
    2012-10-08 16: 14: 26Z
    1. Fungsi serialisasi /deserialisasi tidak dapat diandalkan karena tergantung pada implementasi . Anda juga ingin mengganti c.f[k] = escape(a[k]); dengan Unicode-safe c.f[k] = encodeURIComponent(a[k]); dan eval('b.' + k + ' = ' + unescape(data.f[k])); dengan b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")");. Tanda kurung diperlukan karena fungsi Anda, jika diserialisasi dengan benar, kemungkinan akan anonim, yang tidak as-valid /Statement /(jadi eval()) akan memberikan pengecualian SyntaxError jika tidak).
      2012-10-08 10: 54: 19Z
    2. Dan typeof adalah operator , jangan menulisnya seolah itu adalah fungsi. Ganti typeof(a[k]) dengan typeof a[k].
      2012-10-08 10: 57: 19Z
    3. Selain menerapkan saran saya dan menekankan tidak dapat diandalkannya pendekatan ini, saya telah memperbaiki bug-bug berikut: 1. Tidak semua variabel dideklarasikan. 2. for - in tidak difilter untuk properti sendiri. 3. Gaya kode, termasuk referensi, tidak konsisten.
      2012-10-08 16: 17: 41Z
    4. @ PointedEars apa perbedaan praktisnya? spec mengatakan the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent. Saya tidak melihat perbedaan fungsional.
      2014-01-06 19: 34: 47Z
    5. @ Michael Bagian yang Anda kutip dimulai dengan Note *in particular* that …. Tetapi spesifikasi nilai pengembalian dimulai dengan An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Nilai pengembalian dapat function foo () {} - dengan asumsi implementasi sesuai .
      2014-01-11 13: 17: 38Z

    Anda juga bisa mengganti metode Storage setItem(key,value) dan getItem(key) default untuk menangani objek /array seperti tipe data lainnya. Dengan begitu, Anda cukup menelepon localStorage.setItem(key,value) dan localStorage.getItem(key) seperti biasa.

    Saya belum mengujinya secara ekstensif, tetapi tampaknya berhasil tanpa masalah untuk proyek kecil yang saya kerjakan.

     
    Storage.prototype._setItem = Storage.prototype.setItem;
    Storage.prototype.setItem = function(key, value)
    {
      this._setItem(key, JSON.stringify(value));
    }
    
    Storage.prototype._getItem = Storage.prototype.getItem;
    Storage.prototype.getItem = function(key)
    {  
      try
      {
        return JSON.parse(this._getItem(key));
      }
      catch(e)
      {
        return this._getItem(key);
      }
    }
    
        
    22
    2011-04-26 15: 42: 43Z
    1. Ini dianggap praktik buruk untuk mengubah API objek bawaan /bawaan. Lihat jawaban lain untuk solusi lain.
      2011-09-07 12: 32: 21Z
    2. Bagus, dengan asumsi Anda tidak pernah ingin menggunakan pustaka yang bergantung pada spesifikasi.
      2014-06-08 14: 07: 34Z

    Saya tiba di pos ini setelah mengenai pos lain yang telah ditutup sebagai duplikat dari ini - berjudul 'bagaimana cara menyimpan array di penyimpanan lokal?'. Yang tidak masalah kecuali kedua utas benar-benar memberikan jawaban lengkap tentang bagaimana Anda dapat mempertahankan array di localStorage - namun saya telah berhasil membuat solusi berdasarkan informasi yang terkandung di kedua utas.

    Jadi jika ada orang lain yang ingin dapat mendorong /pop /menggeser item dalam sebuah array, dan mereka ingin array itu disimpan di localStorage atau memang sessionStorage, ini dia:

     

    Storage.prototype.getArray = function(arrayName) {
      var thisArray = [];
      var fetchArrayObject = this.getItem(arrayName);
      if (typeof fetchArrayObject !== 'undefined') {
        if (fetchArrayObject !== null) { thisArray = JSON.parse(fetchArrayObject); }
      }
      return thisArray;
    }
    
    Storage.prototype.pushArrayItem = function(arrayName,arrayItem) {
      var existingArray = this.getArray(arrayName);
      existingArray.push(arrayItem);
      this.setItem(arrayName,JSON.stringify(existingArray));
    }
    
    Storage.prototype.popArrayItem = function(arrayName) {
      var arrayItem = {};
      var existingArray = this.getArray(arrayName);
      if (existingArray.length > 0) {
        arrayItem = existingArray.pop();
        this.setItem(arrayName,JSON.stringify(existingArray));
      }
      return arrayItem;
    }
    
    Storage.prototype.shiftArrayItem = function(arrayName) {
      var arrayItem = {};
      var existingArray = this.getArray(arrayName);
      if (existingArray.length > 0) {
        arrayItem = existingArray.shift();
        this.setItem(arrayName,JSON.stringify(existingArray));
      }
      return arrayItem;
    }
    
    Storage.prototype.unshiftArrayItem = function(arrayName,arrayItem) {
      var existingArray = this.getArray(arrayName);
      existingArray.unshift(arrayItem);
      this.setItem(arrayName,JSON.stringify(existingArray));
    }
    
    Storage.prototype.deleteArray = function(arrayName) {
      this.removeItem(arrayName);
    }
    

    contoh penggunaan - menyimpan string sederhana dalam array localStorage:

     
    localStorage.pushArrayItem('myArray','item one');
    localStorage.pushArrayItem('myArray','item two');
    

    contoh penggunaan - menyimpan objek dalam array sessionStorage:

     
    var item1 = {}; item1.name = 'fred'; item1.age = 48;
    sessionStorage.pushArrayItem('myArray',item1);
    
    var item2 = {}; item2.name = 'dave'; item2.age = 22;
    sessionStorage.pushArrayItem('myArray',item2);
    

    metode umum untuk memanipulasi array:

     
    .pushArrayItem(arrayName,arrayItem); -> adds an element onto end of named array
    .unshiftArrayItem(arrayName,arrayItem); -> adds an element onto front of named array
    .popArrayItem(arrayName); -> removes & returns last array element
    .shiftArrayItem(arrayName); -> removes & returns first array element
    .getArray(arrayName); -> returns entire array
    .deleteArray(arrayName); -> removes entire array from storage
    
        
    21
    2014-05-07 14: 07: 26Z
    1. Ini adalah seperangkat metode yang sangat berguna untuk memanipulasi array yang disimpan di localStorage atau sessionStorage, dan layak mendapatkan lebih banyak kredit daripada yang ditarik. @Andy Lorenz Terima kasih telah meluangkan waktu untuk berbagi!
      2017-08-21 08: 19: 13Z

    Rekomendasikan penggunaan pustaka abstraksi untuk banyak fitur yang dibahas di sini serta kompatibilitas yang lebih baik. Banyak opsi:

    13
    2015-07-07-01 23: 13: 24Z

    Lebih baik Anda menjadikan fungsi sebagai setter dan pengambil untuk localStorage , dengan cara ini Anda akan memiliki kontrol yang lebih baik dan tidak perlu mengulangi penguraian JSON dan semuanya. itu bahkan akan menangani ("") kunci kosong /case data Anda dengan lancar.

     
    function setItemInStorage(dataKey, data){
        localStorage.setItem(dataKey, JSON.stringify(data));
    }
    
    function getItemFromStorage(dataKey){
        var data = localStorage.getItem(dataKey);
        return data? JSON.parse(data): null ;
    }
    
    setItemInStorage('user', { name:'tony stark' });
    getItemFromStorage('user'); /* return {name:'tony stark'} */
    
        
    11
    2018-10-05 12: 15: 17Z

    Saya telah memodifikasi sedikit salah satu jawaban terpilih. Saya penggemar memiliki fungsi tunggal, bukan 2 jika tidak diperlukan.

     
    Storage.prototype.object = function(key, val) {
        if ( typeof val === "undefined" ) {
            var value = this.getItem(key);
            return value ? JSON.parse(value) : null;
        } else {
            this.setItem(key, JSON.stringify(val));
        }
    }
    
    localStorage.object("test", {a : 1}); //set value
    localStorage.object("test"); //get value
    

    Juga, jika tidak ada nilai yang ditetapkan, itu mengembalikan null, bukan false. false memiliki arti, null tidak.

        
    8
    2016-06-23 11: 28: 07Z
    1. Tidak seperti API localStorage, perpustakaan saya mengembalikan tidak terdefinisi ketika mencoba untuk mendapatkan nilai kunci yang tidak ada. Saya setuju salah memiliki arti, tetapi demikian juga null . Variabel yang disetel ke null adalah tidak ada nilai apa pun (tetapi adalah ditetapkan), sedangkan tidak terdefinisi adalah tidak diinisialisasi .
      2018-01-22 17: 35: 29Z

    Peningkatan pada jawaban @Guria:

     
    Storage.prototype.setObject = function (key, value) {
        this.setItem(key, JSON.stringify(value));
    };
    
    
    Storage.prototype.getObject = function (key) {
        var value = this.getItem(key);
        try {
            return JSON.parse(value);
        }
        catch(err) {
            console.log("JSON parse failed for lookup of ", key, "\n error was: ", err);
            return null;
        }
    };
    
        
    6
    2014-09-22 20: 34: 19Z

    Anda dapat menggunakan localDataStorage untuk secara transparan menyimpan tipe data javascript (Array, Boolean, Date, Float, Integer , String dan Object). Ini juga memberikan kebingungan data ringan, secara otomatis memampatkan string, memfasilitasi kueri menurut kunci (nama) serta nilai kueri menurut (kunci), dan membantu untuk menegakkan penyimpanan bersama tersegmentasi dalam domain yang sama dengan kunci awalan.

    [PENOLAKAN] Saya adalah penulis utilitas [/PENOLAKAN]

    Contoh:

     
    localDataStorage.set( 'key1', 'Belgian' )
    localDataStorage.set( 'key2', 1200.0047 )
    localDataStorage.set( 'key3', true )
    localDataStorage.set( 'key4', { 'RSK' : [1,'3',5,'7',9] } )
    localDataStorage.set( 'key5', null )
    
    localDataStorage.get( 'key1' )   -->   'Belgian'
    localDataStorage.get( 'key2' )   -->   1200.0047
    localDataStorage.get( 'key3' )   -->   true
    localDataStorage.get( 'key4' )   -->   Object {RSK: Array(5)}
    localDataStorage.get( 'key5' )   -->   null
    

    Seperti yang Anda lihat, nilai-nilai primitif dihormati.

        
    5
    2017-07-17 17: 03: 22Z
    1. Ini adalah sumber yang cemerlang dan hanya apa yang saya butuhkan. Saya sedang melakukan aplikasi Ionic dengan AngularJS di mana saya perlu menyimpan objek javascript tertentu di localStorage dan sampai saat ini saya baru saja melakukan JSON.parse dan JSON.stringify, dan mereka bekerja, tetapi itu sedikit lebih rumit daripada bisa hanya menggunakan utilitas seperti ini. Saya akan mencobanya.
      2018-01-21 03: 30: 06Z

    Opsi lain adalah menggunakan plugin yang ada.

    Misalnya persisto adalah proyek sumber terbuka yang menyediakan antarmuka yang mudah ke penyimpanan lokal /sesiStorage dan otomatisasi kegigihan untuk bidang formulir (input, tombol radio, dan kotak centang).

     fitur persisto

    (Penafian: Saya penulis.)

        
    4
    2016-06-16 19: 55: 20Z
    1. Masih mengerjakan readme saya, tetapi saya versi tidak memerlukan jQuery, seperti yang tampak persisto, tetapi memang memberikan alternatif untuk berurusan dengan Objek elemen jQuery. Saya akan menambahkan lebih banyak dalam waktu dekat, karena saya bekerja lebih banyak dengannya, untuk membantunya lebih lanjut menangani Objek jQuery yang berbeda dan memelihara hal-hal seperti data yang persisten. Selain itu, +1 untuk mencoba memberikan solusi yang lebih sederhana! Juga, ia menggunakan semua metode tradisional localStroage; exp: var lsh = new localStorageHelper(); lsh.setItem('bob', 'bill'); Juga termasuk acara.
      2016-07-11 19: 28: 11Z

    Anda dapat menggunakan ejson untuk menyimpan objek sebagai string.

      

    EJSON adalah ekstensi JSON untuk mendukung lebih banyak jenis. Ini mendukung semua jenis JSON-safe, serta:

         

    Semua serialisasi EJSON juga JSON yang valid. Misalnya objek dengan tanggal dan buffer biner akan diserialisasi dalam EJSON sebagai:

     
    {
      "d": {"$date": 1358205756553},
      "b": {"$binary": "c3VyZS4="}
    }
    

    Ini pembungkus localStorage saya menggunakan ejson

    https://github.com/UziTech/storage.js

    Saya menambahkan beberapa jenis ke pembungkus saya termasuk ekspresi dan fungsi reguler

        
    4
    2016-07-28 15: 41: 31Z

    http://rhaboo.org adalah lapisan gula penyimpanan lokal yang memungkinkan Anda menulis hal-hal seperti ini:

     
    var store = Rhaboo.persistent('Some name');
    store.write('count', store.count ? store.count+1 : 1);
    store.write('somethingfancy', {
      one: ['man', 'went'],
      2: 'mow',
      went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
    });
    store.somethingfancy.went[1].mow.write(1, 'lawn');
    

    Itu tidak menggunakan JSON.stringify /parse karena itu tidak akurat dan lambat pada objek besar. Sebagai gantinya, setiap nilai terminal memiliki entri Penyimpanan lokal.

    Anda mungkin bisa menebak bahwa saya mungkin ada hubungannya dengan rhaboo ;-)

    Adrian.

        
    3
    2014-10-01 11: 14: 11Z

    Saya membuat pembungkus minimalis lainnya dengan hanya 20 baris kode untuk memungkinkan menggunakannya seperti seharusnya:

     
    localStorage.set('myKey',{a:[1,2,5], b: 'ok'});
    localStorage.has('myKey');   // --> true
    localStorage.get('myKey');   // --> {a:[1,2,5], b: 'ok'}
    localStorage.keys();         // --> ['myKey']
    localStorage.remove('myKey');
    

    https://github.com/zevero/simpleWebstorage

        
    3
    2016-09-28 10: 30: 11Z

    Untuk pengguna Skrip yang bersedia menyetel dan mendapatkan properti yang diketik:

     
    /**
     * Silly wrapper to be able to type the storage keys
     */
    export class TypedStorage<T> {
    
        public removeItem(key: keyof T): void {
            localStorage.removeItem(key);
        }
    
        public getItem<K extends keyof T>(key: K): T[K] | null {
            const data: string | null =  localStorage.getItem(key);
            return JSON.parse(data);
        }
    
        public setItem<K extends keyof T>(key: K, value: T[K]): void {
            const data: string = JSON.stringify(value);
            localStorage.setItem(key, data);
        }
    }
    

    Contoh penggunaan :

     
    // write an interface for the storage
    interface MyStore {
       age: number,
       name: string,
       address: {city:string}
    }
    
    const storage: TypedStorage<MyStore> = new TypedStorage<MyStore>();
    
    storage.setItem("wrong key", ""); // error unknown key
    storage.setItem("age", "hello"); // error, age should be number
    storage.setItem("address", {city:"Here"}); // ok
    
    const address: {city:string} = storage.getItem("address");
    
        
    2
    2018-05-30 11: 06: 17Z

    Berikut beberapa versi kode yang diposkan oleh @danott

    Ini juga akan menerapkan nilai hapus dari penyimpanan lokal dan menunjukkan cara menambahkan layer Getter dan Setter jadi alih-alih

    localstorage.setItem(preview, true)

    Anda dapat menulis

    config.preview = true

    Oke di sini sudah pergi:

     
    var PT=Storage.prototype
    
    if (typeof PT._setItem >='u') PT._setItem = PT.setItem;
    PT.setItem = function(key, value)
    {
      if (typeof value >='u')//..ndefined
        this.removeItem(key)
      else
        this._setItem(key, JSON.stringify(value));
    }
    
    if (typeof PT._getItem >='u') PT._getItem = PT.getItem;
    PT.getItem = function(key)
    {  
      var ItemData = this._getItem(key)
      try
      {
        return JSON.parse(ItemData);
      }
      catch(e)
      {
        return ItemData;
      }
    }
    
    // Aliases for localStorage.set/getItem 
    get =   localStorage.getItem.bind(localStorage)
    set =   localStorage.setItem.bind(localStorage)
    
    // Create ConfigWrapperObject
    var config = {}
    
    // Helper to create getter & setter
    function configCreate(PropToAdd){
        Object.defineProperty( config, PropToAdd, {
          get: function ()      { return (  get(PropToAdd)      ) },
          set: function (val)   {           set(PropToAdd,  val ) }
        })
    }
    //------------------------------
    
    // Usage Part
    // Create properties
    configCreate('preview')
    configCreate('notification')
    //...
    
    // Config Data transfer
    //set
    config.preview = true
    
    //get
    config.preview
    
    // delete
    config.preview = undefined
    

    Baiklah, Anda dapat menghapus bagian alias dengan .bind(...). Namun saya hanya memasukkannya karena sangat bagus untuk mengetahui hal ini. Saya menghabiskan waktu berjam-jam untuk mencari tahu mengapa get = localStorage.getItem; sederhana tidak berfungsi

        
    1
    2015-02-10 20: 25: 37Z

    Saya membuat sesuatu yang tidak merusak objek Penyimpanan yang ada, tetapi membuat pembungkus sehingga Anda dapat melakukan apa yang Anda inginkan. Hasilnya adalah objek normal, tidak ada metode, dengan akses seperti objek apa pun.

    Hal yang saya buat.

    Jika Anda ingin 1 localStorage properti menjadi ajaib:

     
    var prop = ObjectStorage(localStorage, 'prop');
    

    Jika Anda memerlukan beberapa:

     
    var storage = ObjectStorage(localStorage, ['prop', 'more', 'props']);
    

    Semua yang Anda lakukan untuk prop, atau objek di dalam storage akan secara otomatis disimpan ke localStorage. Anda selalu bermain dengan objek nyata, sehingga Anda dapat melakukan hal-hal seperti ini:

     
    storage.data.list.push('more data');
    storage.another.list.splice(1, 2, {another: 'object'});
    

    Dan setiap objek baru di dalam objek yang dilacak akan secara otomatis dilacak.

    Kelemahan yang sangat besar: tergantung pada Object.observe() sehingga memiliki dukungan browser yang sangat terbatas. Dan sepertinya tidak akan hadir untuk Firefox atau Edge dalam waktu dekat.

        
    1
    2015-11-28 20: 39: 41Z

    Lihat ini

    Katakanlah Anda memiliki array yang disebut film:

     
    var movies = ["Reservoir Dogs", "Pulp Fiction", "Jackie Brown", 
                  "Kill Bill", "Death Proof", "Inglourious Basterds"];
    

    Menggunakan fungsi string, array film Anda dapat diubah menjadi string dengan menggunakan sintaks berikut:

     
    localStorage.setItem("quentinTarantino", JSON.stringify(movies));
    

    Perhatikan bahwa data saya disimpan di bawah kunci yang disebut quentinTarantino.

    Mengambil Data Anda

     
    var retrievedData = localStorage.getItem("quentinTarantino");
    

    Untuk mengonversi dari string kembali ke objek, gunakan fungsi parse JSON:

     
    var movies2 = JSON.parse(retrievedData);
    

    Anda dapat memanggil semua metode array di film2 Anda

        
    1
    2015-12-04 06: 40: 59Z
    1. Perhatikan bahwa hanya tautan jawaban tidak disarankan, jawaban SO harus menjadi titik akhir dari pencarian solusi (vs. persinggahan referensi lainnya, yang cenderung menjadi basi dari waktu ke waktu). Harap pertimbangkan untuk menambahkan sinopsis mandiri di sini, dengan menjaga tautan sebagai referensi.
      2015-12-04 06: 23: 54Z
    2. Perhatikan juga bahwa jawaban Anda tidak memberikan apa pun lebih dari jawaban lima tahun yang ada yang memiliki lebih dari 1500 suara. Saya menghargai bahwa Anda mencoba menjawab pertanyaan saya, tetapi harap periksa apakah jawaban Anda memberikan nilai lebih dari jawaban lain yang lebih lama.
      2015-12-04 19: 10: 23Z

    Untuk menyimpan objek, Anda bisa membuat huruf yang bisa Anda gunakan untuk mendapatkan objek dari string ke objek (mungkin tidak masuk akal). Misalnya

     
    var obj = {a: "lol", b: "A", c: "hello world"};
    function saveObj (key){
        var j = "";
        for(var i in obj){
            j += (i+"|"+obj[i]+"~");
        }
        localStorage.setItem(key, j);
    } // Saving Method
    function getObj (key){
        var j = {};
        var k = localStorage.getItem(key).split("~");
        for(var l in k){
            var m = k[l].split("|");
            j[m[0]] = m[1];
        }
        return j;
    }
    saveObj("obj"); // undefined
    getObj("obj"); // {a: "lol", b: "A", c: "hello world"}
    

    Teknik ini akan menimbulkan beberapa gangguan jika Anda menggunakan huruf yang Anda gunakan untuk membagi objek, dan itu juga sangat eksperimental.

        
    1
    2016-05-21 16: 48: 56Z

    Contoh kecil perpustakaan yang menggunakan penyimpanan lokal untuk melacak pesan yang diterima dari kontak:

     
    // This class is supposed to be used to keep a track of received message per contacts.
    // You have only four methods:
    
    // 1 - Tells you if you can use this library or not...
    function isLocalStorageSupported(){
        if(typeof(Storage) !== "undefined" && window['localStorage'] != null ) {
             return true;
         } else {
             return false;
         }
     }
    
    // 2 - Give the list of contacts, a contact is created when you store the first message
     function getContacts(){
        var result = new Array();
        for ( var i = 0, len = localStorage.length; i < len; ++i ) {
            result.push(localStorage.key(i));
        }
        return result;
     }
    
     // 3 - store a message for a contact
     function storeMessage(contact, message){
        var allMessages;
        var currentMessages = localStorage.getItem(contact);
        if(currentMessages == null){
            var newList = new Array();
            newList.push(message);
            currentMessages = JSON.stringify(newList);
        }
        else
        {
            var currentList =JSON.parse(currentMessages);
            currentList.push(message);
            currentMessages = JSON.stringify(currentList);
        }
        localStorage.setItem(contact, currentMessages);
     }
    
     // 4 - read the messages of a contact
     function readMessages(contact){
    
        var result = new Array();
        var currentMessages = localStorage.getItem(contact);
    
        if(currentMessages != null){
            result =JSON.parse(currentMessages);
        }
        return result;
     }
    
        
    1
    2017-02-17 15: 07: 45Z

    Lewati penyimpanan lokal

     
    var retrievedData = localStorage.getItem("MyCart");                 
    
    retrievedData.forEach(function (item) {
       console.log(item.itemid);
    });
    
        
    - 9
    2018-10-01 11: 31: 37Z
    1. Penyimpanan Lokal tidak berfungsi seperti ini. Anda terbatas pada string ... serialisasidiperlukan.
      2017-04-01 20: 05: 10Z
sumber ditempatkan sini