質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

Q&A

3回答

809閲覧

「Airbnb JavaScript Style Guide」の引数への再代入禁止ルール

think49

総合スコア18164

ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

2グッド

4クリップ

投稿2019/02/09 04:04

編集2019/02/09 08:09

Airbnb JavaScript Style Guide

「Airbnb JavaScript Style Guide」では引数へ再代入しない規約になっています。

  • 7.13 パラメータを再割り当てしない。eslint: no-param-reassign

Why? Reassigning parameters can lead to unexpected behavior, especially when accessing the arguments object. It can also cause optimization issues, especially in V8.

なぜ? 特に argumentsオブジェクトにアクセスするとき、パラメータを再割り当てすると予期しない動作をする可能性があります。

argumentsオブジェクトが破壊される (Sloppy Mode限定)

特に argumentsオブジェクトにアクセスするとき、パラメータを再割り当てすると予期しない動作をする可能性があります。

これはおそらく、Sloppy Modeで arguments オブジェクトの要素値を書き換えてしまう動作を表していると想像します。

JavaScript

1// Sloppy Mode 2function sloppy (a) { 3 a += 2; 4 console.log(a); // 3 5 console.log(arguments[0]); // 3 (書き換えられてしまう) 6} 7 8// Strict Mode 9function strict (a) { 10 'use strict'; 11 a += 2; 12 console.log(a); // 3 13 console.log(arguments[0]); // 1 (書き換わらない) 14} 15 16sloppy(1); 17strict(1);

(2019/02/09 16:34追記)
@maisumakun さんより、Strict Modeではarguments破壊されないという指摘を頂きましたので、コードを追記しました。

事象発生の条件は3つあります。

  1. Sloppy Mode である (Strict Modeではない)
  2. 引数 a を再代入する
  3. arguments[0] を参照する

argumentsを破壊させるコードを書くメリット

そもそも、arguments破壊の条件を満たしたコードを書くメリットはあるのでしょうか。
私のコーディングスタイルでは、「引数名による参照」と「arguments[i]による参照」は二者択一であり、それぞれの引数に対してどちらで参照するかを予め決めておきます(参照法を一つにする事でシンプルに書ける為)。

  • 第一引数 … 引数 a で参照する
  • 第二引数以降 … arguments[i] で参照する

従って、条件2と条件3が同時に成立する事はなく、この事象が発生する可能性は0になります。

質問

Q1. argumentsの破壊条件を成立したコードを書くメリットはありますか。あるとしたら、どんなコードが考えられますか。

特にV8では最適化の問題も発生する可能性があります。

Q2. V8最適化問題の詳細をご存知の方は教えて下さい。
Q3. V8最適化問題は現行の最新版である「Google Chrome v72.0.3626.96」でも残存しているのでしょうか。

bochan2, Lhankor_Mhy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

Q1. それが必要な状況にどんなコードが考えられますか。

...argsのようなspread付き引数を、対応していないブラウザのためにコンパイルした場合、arguments経由のアクセスとなります。そして、function foo(a, ...rest)のような引数の持たせ方だった場合、コンパイルすると

javascript

1function foo(a) { 2 for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 3 rest[_key - 1] = arguments[_key]; 4 } 5 6}

のように、「aは配列から、restargumentsから取得」という実行になります。

もっとも、再代入はargumentsのアクセスより後で起きるものなので、速度の影響は考えづらい面もあります。

投稿2019/02/09 06:54

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2019/02/09 07:41 編集

私の質問が不適切でしたので、質問文(Q1)を修正しました。 第二引数以降を可変引数にする為に、arguments を利用するコードは私も書いたことがあります。 しかし、この場合、第一引数を書き換えても、arguments[0] で第一引数を参照しないので、arguments破壊の影響を受けません。 破壊の影響を受ける為には、「引数 a を再代入する」「arguments[0] を参照する」が必要条件ですが、そのようなコードを書く意味はありますか、が Q1. の意図でした。 > Strictモードでは影響しないものもあるようです。 情報ありがとうございます。 Google Chrome 72.0.3626.96でStrict Modeではargumentsが破壊されない事を確認しましたので、質問文に追記しました。
guest

0

なにを気にしてるのかイマイチわかりませんが、
ローカルのオブジェクトな限りなにをどうしようが自由です。

ルールというのはニンゲンが見てわかりやすくする、ってだけのはなしなんで、
あとは個々のニンゲンの気分の問題にしかならないので、ご自由にどうぞ。

投稿2019/02/09 04:12

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2019/02/09 04:29

クローズドソース、自分一人でコーディングしている場合は、仰る通りだと思います。 最も、「V8における最適化の問題」は自分一人でも「どうでもいい問題」ではなさそうですが…。
y_waiwai

2019/02/09 04:39

最適化の問題と言ってもせいぜい最適化されないぐらいのことなんで、まあいいんじゃないかと。 チームで開発する場合のコーディングルール的なものは、従わなければならない的なもんなんで、理由を聞いてもしようがない、とは思っとります
think49

2019/02/09 05:27 編集

規約は盲目的に守るものではなく、意図を理解して使うものと認識しています。 最適化問題については、最適化の有無による影響力の大きさによって捉え方が変わると思います。
y_waiwai

2019/02/09 08:29

それがそのまま個々のニンゲンの気分によるものなので、あなたはそうすればよろしい。 そう考えないニンゲンもいるということで。
think49

2019/02/09 08:34

そうですね。意見は人それぞれだと私も思います。
guest

0

下記のJSPerfを作成し、私の手元のChrome、Firefox、Edge(いずれもWin10上で最新)で試しましたが、有意義な差は出ませんでした。

https://jsperf.com/param-reassign

Node.jsの古いバージョンでは差が出る可能性があるため次のようなコードを作りました。

JavaScript

1const Benchmark = require('benchmark'); 2 3const reassign = () => { 4 const f = foo => { 5 foo = Number(foo); 6 return foo * foo + foo; 7 }; 8 const nums = [2, "3", [5]]; 9 const results = nums.map(f); 10}; 11 12const no_reassign = () => { 13 const f = foo => { 14 const bar = Number(foo); 15 return bar * bar + bar; 16 }; 17 const nums = [2, "3", [5]]; 18 const results = nums.map(f); 19}; 20 21const suite = new Benchmark.Suite; 22 23suite 24.add('Reassignment', reassign) 25.add('No Reassignment', no_reassign) 26.on('cycle', event => console.log(String(event.target))) 27.run({ 'async': true });

WSL上のUbuntu 18.04 LTSでNode.js 6.16.0, 8.15.0, 10.15.1, 11.9.0で上記を試しましたが、こちらも有意義な差は出ませんでした。

SafariやBabelで変換後のIEについては未調査ですので確実とは言えませんが、現行環境では意味のあるパフォーマンスの差は無いと推測されます。

投稿2019/02/09 05:45

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2019/02/09 06:09

わざわざ検証コードを用意して頂き、ありがとうございます。 私の環境(Chrome 72.0.3626 / Windows 10 0.0.0)でも優位な差はありませんでした。 優劣は軽微で、優劣が逆転したり、ほぼ同等だったり安定しません。 arguments破壊については、どう思われますか。
raccy

2019/02/09 07:52

「そもそもargumentsは使わない」の一言に尽きますね。Babelの変換でargumentsが現れて、それでおかしくなったら、そればBabel側のバグでしょというスタンスです。 私もあちらの質問でAirbnbの話を見て、「?」と思ってしまいました。オーバーロードの代わりに型変換して再代入はPythonやRubyではごく普通に使われているテクニックだったので。
think49

2019/02/09 08:33

なるほど。@raccy さんらしい答えですね。 引数名とargumentsは衝突しますが、Rest Parametersは引数そのものなので、衝突対象がないのが良いです。 function foo (a, ...args) {} 私がargumentsを使う時にも、Rest Parameters を arguments で代用するスタイルで書いています。 また、アロー関数を使う時にはargumentsが使えないので、Rest Parameters しか選択肢がないですね。 > オーバーロードの代わりに型変換して再代入はPythonやRubyではごく普通に使われているテクニックだったので。 jQuery() のように引数の意味が変わるなら、別の変数名で再定義しますが、意味が変わらないなら、私も再代入を積極的に使っています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問