ある日、Qiitaで面白い記事を発見。
▼ JavaScriptで+++は許されない+ ++は許される
記事で話題になっているのは、こういう式
▼ インクリメント(++)と加算(+)の組み合わせ
1 2 |
var a=0, b=13; console.log(a+++b); |
なんかエラーが出ると書かれています。まあコメントでも指摘されてる通り、ChromeでもFireFoxでもエラーは出ないんですけどね・・・(のちに訂正されました)
それはともかく この a+++b の書き方
この実行後に a と b の値は何になるか、
それを考えると次の3つの解釈ができます。
- a : 1, b : 13
- a : 0, b : 14
- a : 不明, b : 不明
この内の2つは間違い。
この例からも分かるように、
バグを生み出すリスクもあるかもしれません。
まず前置と後置の動作の違いについて
前置と後置の違いはこう。
- 前置(++a , --a)
インクリメント(デクリメント)を先に行い、その加算(減算)された値を返す。
- 後置(a++, a++)
インクリメント(デクリメント)を後に行い、その加算(減算)される前の値を返す
端的に書くなら、こういう感じですね。
さらに具体的なコード例で示すとこうなります。
▼ 前置の分かりやすいコード例
1 2 3 4 5 |
var x = 1000000; console.log('x : ', ++x); /// x : 1000001 console.log('x : ', x); /// x : 1000001 |
▼ 後置の分かりやすいコード例
1 2 3 4 5 |
var x = 1000000; console.log('x : ', x++); /// x : 1000000 console.log('x : ', x); /// x : 1000001 |
前置だと
++x を実行した時点で
x : 1000001 なのに対し、
後置の
x++ だとそれが実行された時点では
x : 1000000 のまま。
加算を先にするか、後にするか、
減算を先にするか、後にするか
たったこれだけのことですが、
書き方によってはバグにつながる誤解を生みます。
前置と後置の優先順位。a+++bの答えは?
ここで冒頭の記事に戻ってみます。
この記事で話題になってるのが、この書き方
▼ このコードの答えは・・・?
1 2 3 |
var a = 0, b = 13, console.log(a+++b); /// 14 |
コンソール表示が 14 はどうでもいいこと。
問題は実行後に a と b の値が何になるか ですね。
これは前置と後置の優先順位を知る必要があります。
その答えはMDNに書いてありました。
以下の表は優先順位の最も高いもの (21) から最も低いもの (1) の順に並べられています。
優先順位 演算子の種類 結合性 演算子 18 後置インクリメント なし ... ++ 後置デクリメント … -- 17 前置インクリメント 右から左 ++ … 前置デクリメント -- …
後置が 18 の優先順位。
前置は 17 の優先順位。
後置 > 前置
こういう優先順位です。
だから a+++b はこう書くのと同じなんです。
1 2 |
var a = 0, b = 13, console.log((a++)+b); |
つまり、 a と b の値は、
a : 1 , b : 13
これは優先順位を分かってないと迷いそう。
正直言って a+++b は悪手としか思えません。
インクリメントの前置後置は平易な書き方をすべき
結局結論は何かというと・・・
紛らわしい書き方はすべきでないこと
そういった書き方をいくつか考えてみました。
▼ 前置後置の紛らわしいバッドコード例
1 2 3 4 5 6 7 |
var a = 1, b = 2; console.log(a+++b); /// 3 console.log(a); /// 2 console.log(b); /// 2 |
1 2 3 4 5 6 7 |
var a = 2, b = 1; console.log(a---b); /// => 1 console.log(a); /// => 1 console.log(b); /// => 1 |
1 2 3 4 5 6 7 |
var a = 2, b = 2; console.log(a---b+++a); /// => 1 console.log(a); /// => 1 console.log(b); /// => 3 |
分かりにくい、すごく分かりにくい。
3番目に至っては脳がかなり混乱します。
もちろん優先順位を理解済みなら問題ありません。
- 後置インクリメント > 前置インクリメント
- 後置デクリメント > 前置デクリメント
でも全ての人が理解してると限らないし、
生半可な知識で思い込みしてしまう人もいます。
だから書き方自体を気を付けるべきですね。
▼ 例えばこういう感じで
1 2 3 4 5 6 7 |
var a = 2, b = 2; console.log((a--)-(b++)+a); /// => 1 console.log(a); /// => 1 console.log(b); /// => 3 |
これでも若干分かりにくい・・・(-_-)
でも変に気取ったトリッキーな書き方をするくらいなら、こういう分かりやすい平易な書き方にする方が親切だと思います。どちらかと言えば。
間違いがあればコメント欄からご指摘ください。ではまた