Uncaught Syntaxerror: Unexpected token u

概要

このエラーメッセージが出たのが、 localStorage に undefined を保存しちゃった ことが原因だったよ、、というお話。

さらに、undefined を JSON.parse したら、再現できます。

経緯

このあいだ、Javascriptでコードを組んでいて、以下のようなエラーメッセージに遭遇しました。

f:id:takemaruhirai:20151216111842p:plain

処理がここで止まって、突如、総ての動作が停止する事態に焦ったのですが、何しろエラーメッセージの情報が少なすぎる 。

なんだ u って

しかも、gulpで Electron + React 環境をビルドしていたためか、正確なエラーの位置も分からない状態でした。 コードの中をあちこち「u」で検索しましたが、そんな変数は見つからず。 うっかり入力ミスで「u」を書き込んでいた、ということもありませんでした。

仕方なく「Uncaught Syntaxerror: Unexpected token u」で検索すると、次のような情報に出会いました。

2013-04-21

  • "uncaught syntaxerror unexpected token u"と出る
    • コールバックと引数が一致していない。succcesssなのにcomplateで使う引数を使っているとか変数名が間違っている

コールバック?? と思いつつも、コールバック関数を利用している箇所を探しましたが、エラーを起こすような箇所はすぐに見つかりませんでした。 ただ、「引数がおかしい」という見当をつけることにはなりました。

そこで、最近追加した「引数を扱っている」コードをコメントアウトするなどして場所を絞り込んでいくと、見つかりましたよ、原因

以下に、それを再現したコードを掲載します。

obj= {};

localStorage.setItem("Something", JSON.stringify(obj.notCreated));

if (localStorage.getItem("Something")){
    var loadedItem = JSON.parse(localStorage.getItem("Something"));
    console.log(loadedItem);
}

これを HTML に埋め込んで実行すると「Uncaught Syntaxerror: Unexpected token u」が再現できるはずです。

このケースの場合は明らかですが、localStorageundefined が入ってしまっています。

f:id:takemaruhirai:20151216114534p:plain

Somerhing という変数自体が undefined ならばもっと分かりやすいエラーメッセージがでて、localStorageへの格納自体ができないのですが、 Something というオブジェクトのキーが udefined の場合、localStorage に undefined が保存できてしまう ということが分かりました。

localStroage にデータを保存/読込するときは、JSON.stringify/JSON.parse するのがお作法となっていますが、 getItem のほうで読み込んだデータが undefined だと、当然、JSON.parse のところで不都合が生じるわけですね。 これが今回のケースの原因でした。

つまり、もっとも端的に「Uncaught Syntaxerror: Unexpected token u」を再現するならば、

console.log(JSON.parse(undefined));

これで十分です。このままのコードを書くケースはまず無いと思いますが、localStorageにオブジェクトを保存する際にはご注意ください。