localStorage にオブジェクトを保存したい

オブジェクトを文字列に変換したい

localStorage にオブジェクトを保存したかったのですが、
文字列にどう変換したら良いのかわからず調べたので、その際のメモです。

toString() をみてみる

まず配列を toString() してみます。
配列オブジェクトは Object の toString() メソッドをオーバーライドしています。
配列の toString メソッドは内部的に join() を呼び出し、すべての要素をカンマで区切って一つの文字列に収めて返します。
Array.prototype.toString() - JavaScript | MDN

["orange", "apple"].toString() // => 'orange,apple'


他のタイプのオブジェクトについてもみてみます。
それぞれのオブジェクト毎に用意されている toString メソッドが呼び出されます。

const f = function(x){return x + 1;} 
f.toString() // => 'function(x){return x + 1;}'

const d = new Date
d.toString() // => 'Thu Dec 05 2023 20:00:00 GMT+0900 (日本標準時)'

しかしオブジェクトに関しては'{orange: 100, apple: 50}'のように返ってきません。

const o = {orange: 100, apple: 50}
o.toString() // => '[object Object]'

toString() メソッドは Object の子孫にあたるあらゆるオブジェクトに継承されていますが、上記のように、カスタムオブジェクト中で上書きされていない場合、 toString() は "[object type]" という文字列を返します。
Object.prototype.toString() - JavaScript | MDN

また、nullundefinedについては以下のように、TypeError が返ってきます。

const n = null
n.toString() // => Uncaught TypeError: Cannot read properties of null (reading 'toString')

const u = undefined
u.toString() // => Uncaught TypeError: Cannot read properties of undefined (reading 'toString')

String()

次に String() メソッドを使ってみてみます。
String - JavaScript | MDN

String(["orange", "apple"]) // => 'orange,apple'
String(function(x){return x + 1;}) // => 'function(x){return x + 1;}'
String(new Date) // => 'Thu Dec 05 2023 20:00:00 GMT+0900 (日本標準時)'
String({orange: 100, apple: 50}) // => '[object Object]'

オブジェクトに関しては変わらず "[object type]" が返ってきています。

nullundefinedについては以下のようになります。

String(null) // => 'null'
String(undefined) // => 'undefined'

String - JavaScript | MDN

JSON.stringify()

では、本題のオブジェクトを localStorage に保存したい場合など、オブジェクトを文字列に変換したい場合どうしたら良いでしょうか。
JSON.stringify() を使います。
JSON.stringify() - JavaScript | MDN

const value = JSON.stringify({orange: 100, apple: 50}) // => '{"orange":100,"apple":50}'
localStorage.setItem('keyname', value)

そして、localStorageから取り出す場合は、JSON.parse()を使います。

const value = localStorage.getItem('keyname')
JSON.parse(value) // => {orange: 100, apple: 50}