前提・実現したいこと
プログラミングを初めて1年半くらいですが、どうしてもわからなかったので、初めて質問させていただきます。
JavaScrip(JSに限らず他の言語でも)で、仮引数に再代入するこは、コーディングする上で避けたほうがよいのでしょうか?
また、仮引数を、constで変数宣言したときのように再代入したときにエラーを出す方法はありますか?
該当のソースコード
JavaScript
1const foo = bar => { 2 bar = bar+1; 3 return bar; 4} 5 6console.log(foo(0)) // => 1
補足情報(FW/ツールのバージョンなど)
Chrome71
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
二元的
回答する前に前提として、
- このコードは良い
- このコードは悪い
のように二元的に捉えるのは良くない事だと思います。
- コードAは~という理由から、~という性質を持つコードBに書き換える事が好ましい
これなら、良いと思います。
ですが、「コードA > コードB」の良し悪し比較の結果だけを覚えるスタンスは良くない事です。
別の視点で見てコードBに悪い点があった場合に気が付きにくいからです。
ですので、良し悪しを覚えるのではなく、改善すべき理由を覚えましょう。
自分の中で確立した「改善点が少ないコード」が、(あなたにとっての)良いコードです。
サンプルコードが不適切
JavaScript
1const foo = bar => { 2 bar = bar+1; 3 return bar; 4}
このサンプルコードは再代入する意味が全くありません。
JavaScript
1const foo = bar => { 2 return bar + 1; 3}
これで良いでしょう。
変数に再代入させるなら、「再代入させるべき理由」を確立して下さい。
コードに対する思想と言い換えてもいいですね。
変数名に込められた意味
私は変数名が意味する範囲を超えていなければ、再代入しても良い(MAY)、と考えます。
JavaScript
1function sample (length) { 2 length = Number(length); 3 4 for (var i = 0; i < length; i++) { 5 console.log(i); 6 } 7} 8 9sample(10);
引数 length
は「Number 型を期待する長さ」であり、Number型に変換しても**「長さ」という意味は変わりません**。
Re: edhwui さん
投稿2019/02/09 03:01
編集2019/02/09 03:05総合スコア18189
0
どちらでも構わない。
ただし「関数は画面に十分収まるぐらいの行数しか無い」ことが前提にとなります。
変数への再代入やオブジェクト自体の変化などの副作用の問題は「プログラマーが副作用に気づけなかったときにバグが発生する」ことです。副作用が見える範囲に書いてあるのであれば、そのような心配はありません。十分に最適化された短い行数の関数であれば、仮引数は常に見える範囲内になるでしょう。よって、仮引数に対しては再代入を禁止する理由はないとなります。
ただし、もう一つの考えがあります。「時としてプログラマーは見える範囲の副作用すら見逃す」というものです。こうなってくると、全く副作用が無い、全てが参照透過な世界に行くしかありません。純粋関数型はそのような世界の一つです。残念ながら、JavaScriptはそのような純粋関数型言語ではありません。そこまで気にするパラノイアにかかっているのであれば、ElmやPureScriptを使った方が安心だと思います。
投稿2019/02/09 03:13
総合スコア21737
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
避けたほうがいいです。
言語に限らずですが、JavaScriptについてはAirbnb JavaScript Style Guideに簡潔に説明されています。
該当項目は7.13 Never reassign parameters(有志日本語訳:7.13 パラメータを再割り当てしない)です。以下日本語訳からの引用です。
7.13 Never reassign parameters. eslint: no-param-reassign
7.13 パラメータを再割り当てしない。eslint: no-param-reassignWhy? Reassigning parameters can lead to unexpected behavior, especially when accessing the arguments object. It can also cause optimization issues, especially in V8.
なぜ? 特に argumentsオブジェクトにアクセスするとき、パラメータを再割り当てすると予期しない動作をする可能性があります。 特にV8では最適化の問題も発生する可能性があります。
また、仮引数を、constで変数宣言したときのように再代入したときにエラーを出す方法ですが、言語レベルではありません。lintツールで検出、警告するようルール設定するのが一般的です。
例えばeslintではno-param-reassignというルールを有効にします。
投稿2019/02/09 02:34
総合スコア805
0
仮引数に再代入するこは、コーディングする上で避けたほうがよいのでしょうか?
君子危うきに近寄らず。
言語問わず使わないで済む箇所は避けるべきです。
速度面や実装面でどうしてもな箇所はその場で相談といった形ですね。
因みにJavaScriptの代入演算子は値渡しなので、
プロパティに対して代入しない限り副作用も何もありません。
しかし、その関数が仮引数をあちこちに引き回しているようなものだと、
想定外の不具合に簡単に遭遇しますので、
引数や変数への再代入は最小限に留めるほうが良いでしょう。
該当のソースコード
単純に可読性の問題で、
「新Aは引数A+1である。その上で引数Aを結果として取り扱う」みたいな文章より、
「戻り値は引数Aに+1した数値である。」の方が自然です。
ついでにアロー関数は{}
を省略すると1行目を即returnするのでこれで終わります。
barという名前もつけず、itで良いかもしれません。
関数名は挙動から推測出来るようにadd1みたいな感じの名前に改名しましょうか。
JavaSceipr
1const add1 = it => it + 1; 2 3console.log(add1(0)) // => 1
という風に、コードは文章なので基本的に行数をつらつら重ねるより、
シンプルにバシッと書いた方が読みやすいものです。
挙動に関して満足行くものが作れるようになってきたら、
「リーダブルコード」などの書籍を読んで可読性に関して勉強してみてくださいね。
投稿2019/02/09 03:40
編集2019/02/09 03:41総合スコア21194
0
JavaScriptではありませんが、言語によっては引数の型で再代入を禁止することが可能です。
- Java…
final
- C言語/C++…
const
(なお、ポインタにconst
を付ける場合、「ポインタ自体」と「指す先」のどちらにconst
をかけるのかという注意が必要です)
投稿2019/02/09 03:12
総合スコア145930
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/09 04:00
退会済みユーザー
2019/02/09 04:15
2019/02/09 04:16
2019/02/09 04:31