Aiki x Developer

javascript

JavaScript 前置インクリメントと後置インクリメントの違いが、いまいちピンとこない人へ

August 3rd, 2020

increment

どうもー、ドイツ在住フリーランスのフルスタックエンジニアのArisaです🇩🇪

さて、今日はJavaScriptのインクリメントのお話。

JavaScript学習しはじめの頃って、値の型には何があってとか、演算子の種類とかから入ると思うんですけど、このインクリメントっていうのが、説明を読んでも、反映結果を見てもさらに混乱するだけという人が多いように思んですね。

それもそのはず、公式ドキュメントのMDN見ても「どうゆうこと?」ってなってしまう説明だし、実際に簡単なインクリメントの計算をさせてみても、ものすごく納得がいかない結果になるから。

JavaScriptを教えていて、質問頻度の高い内容の1つでもあるインクリメント。

この記事では、前置インクリメントと後置インクリメントの違いを、しっかりとなぜそうなるのかを押さえながら解説していきます。

まずMDN

まず何かわからないことがあれば、公式ドキュメントに飛びますね。

MDNはここ数年で割と日本語訳も増えてきましたが、ジャンルによってはまだ訳されていないものもあります。

残念ながら2020年8月の時点で、インクリメントに関しては翻訳はありません。

英語が苦手な人は苦手意識が出てしまうかもしれませんが、Google翻訳とか、DeepLとか使ってもOKです。

MDNがインクリメントについて、説明している部分を読むとこのように書いてあります。

後置インクリメントは加算もするが、加算する前の値を基本的に返す。前置インクリメントは、加算後の値を返す。

うん?

これを読んですぐわかる人って、JSをプログラミング言語の第一言語として学習し始めた人で、あんまりいないんじゃないかと思います。

私も実際使ってみても初めの頃はいまいちピンとこないままでしたから、初学者にはハードル高い説明です。

一応親切に実際のソースコードの例がありますが、余計混乱するんじゃないかなって反映結果です😅

一応見ましょう。

mdn-example

変数に1を加算することまではわかるのですが、なぜ後置インクリメントだと加算されそうなyが加算されていないのか?と思いませんか?

このソースコードだけ見ていても、「これはそういうものとして覚えるしかないのか...」と諦めたくなるので、上記のソースコードをわかりやすく崩してみましょう。

インクリメントを使わず書いてみる

まず、インクリメントを使用せずに、上記MDNのサンプルコードを再現します。

これ、とっても重要です。

インクリメントだけに限らず、特にES6以降のJavaScriptは、いわゆる「省略系の技法」が多く存在します。

アロー関数や、テンプレートリテラル、スプレッド演算子、条件(三項)演算子などが代表的です。

そのほかにも省略系とは直結しませんが、似たタイプで「書き換え可能なタイプ」の技法もあります。

if文 → switch文、for文 → while文、コールバック関数 → Promiseなどが代表的です。

こういう元の原型の技法があって、それを省略なり書き換えなりするタイプの技法は、元の原型の技法でまずは書いてみると、意味がストンと簡単に理解できることが多いです。

インクリメントも同様です。

前置インクリメントは、まだそれ単一で例を見ると理解できないことはないですが、なぜ後置インクリメントと誤差が出てしまうのかについては、そのままでは見えてこないので、元の原型で書きます。

mdn-destructured

どうですか?

インクリメントを使わずに崩して書くだけで、なぜ前置インクリメントという名前の演算子なのか、なぜ後置インクリメントという名前の演算子なのかまでわかりましたね。

このコードを読んだ後でもう一度MDNの文章を読み返すと、加算するタイミングが先に来るのか、後に来るのかということなのだとわかりますね。

実践ではどっちをよく使うの?

上記の例は、あまり実践的ではないかもしれません。

よくあるJavaScriptの練習問題は、簡単な計算をさせたり、console.logでアウトプットさせるものが多いですが、

「で、これができて何になるの?」

というものも多いです。

確かにconsole.logで出力しても、ユーザーからは見えませんし、簡単な計算ができたところで「で?」となるのは当然です。

実際に実践で使われているものを見ることで、どんなときに役立つ技法なのか、また、どちらのインクリメントの方が実戦でよく使われているのかという疑問も解消します。

JavaScriptの技法の1つにfor文というものがありますが、ここには基本構文自体にインクリメントが含まれています。

for文は、繰り返しの処理(ループ)をするときに使用します。

そのほかにもfor...inやfor...of、forEachもありますが、今回はインクリメントの実践に絞りたいので、割愛します。

for文の基本構文は以下です。

for-statment

実際に何かループさせるとインクリメントが見れるので、適当に0から10までの数値を繰り返し生成させるfor文を作ります。

num-loops

変化式に後置インクリメントがあるのが確認できます。

ただし、この例だと変数が1つしかありませんので、前置インクリメントでも後置インクリメントでも反映結果に差はありません。

もう1つ変数を用意して、反映結果に差を出してみます。

まずは後置インクリメント。

postfix-for

そして次は前置インクリメント。

prefix-for

反映結果が明らかに違いますね。

元々のインクリメントを使わない例で、それぞれ見てみましょう。

後置インクリメント崩したもの。

postfix-for-destructured

前置インクリメント崩したもの。

prefix-for-destructured

ここまで見るだけでも、既に前置インクリメントと、後置インクリメントで反映に違いがあるのがわかりましたね。

まだまだこのままでは単純な計算をさせているだけなので、「これができて何かすごいわけ?」となってしまいますが、ここからDOMやイベントと紐付けなんかをすると、SNSのいいね!のような機能にも発展させることができますし、条件分岐を追加すれば、クイズにもなります。

(※ 1ずつ追加にならないのは、for文変化式にもインクリメントがついているからなので、それを外れば1ずつ追加になります)

大抵のこうしたアプリケーションは、ユーザーも規則性のある加算で想定してきますから、変数が2つ以上存在するのであれば、前置インクリメントの方が良いという判断もできます。

逆に変数が1つであれば後置インクリメントでもOKという判断もできます。

このように実践での場合をイメージしやすくするところまで、例を書くことができたり、検証してみることができれば、インクリメントの意味がはっきり理解できます。

まとめ

どうでしたか?

今回は前置インクリメントと後置インクリメントの違いについてでしたが、他の技法の学習の際にも役立つ調べ方や理解の仕方も、今回のような方法が使えます。

省略系の技法はまず分解する。

書き換え系の基本構文は、まずは元の原型の基本構文から書く。

これらを覚えておくと、JavaScriptの基本を抑えることが少しは楽になるので、ぜひ試してみてください。

では、

ちゅーす

Created by Arisa Fukuzaki, © 2019