SyntaxError: Unexpected token }とは何か

Google Chromeのコンソールで, 「(」と打ってEnterしてみましょう.

> (
SyntaxError: Unexpected token }

えっ...? 僕 } なんて打ってないよ... ワケがわからないよ...

いろいろ実験してみましょう.

> (
SyntaxError: Unexpected token }
> -
SyntaxError: Unexpected token }
> +
SyntaxError: Unexpected token }
> ++
SyntaxError: Unexpected token }

どれも } を入力してないのに...

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

という訳で, stackoverflowに投げてみました.

Why Google Chrome console throws “SyntaxError: Unexpected token }” when inputted (.

すると素晴らしい! 見事に解決してしまいました!

chromium/src/third_party/WebKit/Source/WebCore/inspector/InjectedScriptSource.jsの_evaluateOn関数の280行目が鍵.

                expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";

なるほど, withに放り込まれるのかぁ...


ということは, with statementを最初っから閉じることができますね! 遊んでみましょう!

> }{
undefined

ほうほう...パースエラーがでない...

> } 'hoge ' + {
"hoge [object Object]"

これは

with ((window && window.console && window.console._commandLineAPI) || {}) {
} 'hoge ' + {
}

に変換されて, +の後の { と, 内部で付け足された } が一緒になって {} になっちゃった.


Objectをいろいろ作ってみよう.

> } +{ valueOf: function () { return 531; }
531
> } '' + { toString: function () { return 'きゃっほ'; }
"きゃっほ"


回答して下さった人の, この例は評価したい.

> }!{
false
> }!!{
true


Labelを付けたBlockにして, それをちゃんと抜けれる.

> i = 10} labelA: { while (--i) { console.log(i); if (i < 8) break labelA; }
9
8
7
undefined


関数の最後の } としても使える.

> } f = function () { return 100;
function () { return 100;
}

ちゃんと改行されてる...



...という訳で, タイトルに対する答えは,

「入力を内部の処理で囲っているWith statementの最後の } である.」ということになりますね.

Firefoxでも同じような現象が起こりますね.

追記 (2017/04/01)

この挙動は、すでに再現しなくなっていました。面白かったのに、残念…