JavaScriptで複数の変数を宣言する


333

JavaScriptでは、次のように複数の変数を宣言することができます。

var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;

...またはこのように:

var variable1 = "Hello World!",
    variable2 = "Testing...",
    variable3 = 42;

ある方法が他の方法よりも優れている/速いですか?


6
より速く、使用してこのjsperfを私は1つの方法または他のを使用して一貫性の速度ゲインを見ることができませんでした。
Majid Fouladpour 2014年

回答:


344

最初の方法は保守が簡単です。各宣言は1行の1つのステートメントなので、宣言を簡単に追加、削除、および並べ替えることができます。

2番目の方法では、varキーワードとセミコロンが含まれているため、最初または最後の宣言を削除するのは面倒です。また、新しい宣言を追加するたびに、古い行のセミコロンをコンマに変更する必要があります。


67
後で縮小またはパックする予定のコードを記述している場合、2番目の方法では、コンプレッサー(YUI Compressorなど)を使用して、より縮小されたバージョンを作成できます。サイズが考慮事項である場合は、JSLintの提案のできるだけ多くに従うことをお勧めします。
レーン

36
jslintは、2番目の方法の方が正しいと主張していますが、私は同意しません。
ThatGuy

29
2番目の方法は、マイクロ最適化です。すべてのvar宣言は、一度に1つではなく、一度に処理されます。これは、最新のブラウザや最新のコンピュータではそれほど問題ではありません。
webnesto 2012

18
@ 0xc0de:1つのステートメントですべての変数を「効率的」と宣言したことの証明を確認したいと思います。節約された数バイトの問題として効率を測定しているだけなら、多分そうです。しかし、可読性と保守性を考慮すると、特に最新のブラウザーは実行前パスのスコープ内のすべての変数を収集して初期化するため、時期尚早な最適化は通常は間違った方法であることがわかります。個人的には、コードをすばやく理解するのが難しくなり、エラーが発生しやすくなるように、変数をすべて1行または1つのステートメントで宣言していることに気づきました。
ogradyjd 2013

9
効率に関しては、uglifyjsとgoogleクロージャーコンパイラーの両方が、順次varステートメントを自動的に1つに押しつぶし、そのポイントを無効にします(YUIがこれを行わないことがわかる限り、私は十分にテストしていません)。
bhuber 2014

215

保守性に加えて、最初の方法は、事故のグローバル変数の作成の可能性を排除します。

(function () {
var variable1 = "Hello World!" // semicolon is missed out accidently
var variable2 = "Testing..."; // still a local variable
var variable3 = 42;
}());

2番目の方法は許容度が低くなりますが、

(function () {
var variable1 = "Hello World!" // comma is missed out accidently
    variable2 = "Testing...", // becomes a global variable
    variable3 = 42; // a global variable as well
}());

4
いい視点ね。短い場合は、1行で記述することでこの問題を回避できますvar variable1 = "Hello World!", variable2 = "Testing...", variable3 = 42;。行方不明,クラッシュしますが、私は同意することは危険だ
アラムKocharyan

14
strictモードを使用している場合は、このようなグローバルを作成することはできません。
Danyal Aytekin 2012年

1
見た目がすっきりしているので、複数の変数を1行で宣言するのが好きです。とはいえ、誤ってグローバル変数を宣言することは本当に危険です。メモリリークを追跡しているときに、コンマの代わりにセミコロンを使用したために、誤って一度に複数のグローバル変数を宣言した複数のインスタンスに遭遇しました。
smabbott 2013年

+1は1日の半分を費やすだけで、なぜこれら2つの宣言の間に文書化されていない違いがあるのか​​疑問に思い始めました。次に、この回答を読み、コードを慎重にチェックして、間違いを見つけました。休日が必要...
Giedrius

1
私のテキストエディターは、私Possible Fatal Errorが昏睡を逃した場合、私のために万歳をくれます!

33

組織のスコープごとに1 つのvarステートメントを使用するのが一般的です。すべての「スコープ」が同様のパターンに従ってコードを読みやすくする方法。さらに、エンジンはそれらすべてをとにかく上に「巻き上げ」ます。したがって、宣言をまとめておくと、実際に何がより厳密に起こるかを模倣します。


6
同じ「var」宣言を共有せずに宣言をまとめることができます。私はjslint(あなたのリンク)で与えられた説明を理解して受け入れますが、私は結論を共有しません。上記のように、それは何よりもスタイルの問題です。Javaの世界(特に)では、読みやすくするために逆(1行に1つの宣言)をお勧めします。
PhiLho、

もっと読みやすい?人々がそれらを1行に置く唯一の理由は、あなたが言及したJS固有の理由です:JSはすべての宣言を先頭に移動します。それを行わなかった場合、すべての変数は、それらが使用されるポイントに最も近いと宣言します。
Danyal Aytekin、2012年

@ vol7ronはそうではなく、var声明の大きな誤解です。正反対が真です。ドキュメントこの例を
jackweirdy

@jackweirdyあなたは正しいです、そしてそれはケース、不十分な実装、または古いブラウザーのバグでした。その後、コメントを削除しました。
vol7ron 2013

29

このようにすると、より読みやすくなります。

var hey = 23;
var hi = 3;
var howdy 4;

しかし、この方法では、スペースとコード行が少なくて済みます。

var hey=23,hi=3,howdy=4;

スペースの節約には理想的ですが、JavaScriptコンプレッサーがそれを処理してくれます。


15

たぶんこんな感じ

var variable1 = "hello world"
, variable2 = 2
, variable3 = "how are you doing"
, variable4 = 42;

最初または最後の変数を変更する場合を除いて、維持および読み取りは簡単です。


6
通常、セミコロンはコンマファーストを使用して、その問題を防ぐために改行します。var variable1 = "hello world" \ n、variable2 = 2 \ n、variable3 = "元気ですか" \ n、variable4 = 42 \ n; \ n
BrianFreud

2
これはHaskell構文です。私はどういうわけかそれがjavascriptで推奨されない/一般的な実践ではないと感じています
shamanSK

14

それは単に個人的な好みの問題です。空白を取り除いた場合に2番目の形式で保存される数バイト以外は、これら2つの方法に違いはありません。


2つ目は、数バイトを節約します。
ソフィーアルパート

ベンアルパート:どのように考えていますか?
Josh Stodola

空白を削除すると、「var foo = "hello"、bar = "world";」よりも 宣言は 'var foo = "hello"; var bar = "world";'よりも文字数が少ない 人気のあるサイトがある場合は、JSで数バイトを節約すると役立ちます(変数名なども最小限に抑える必要があります)
Brian Campbell

JavaScriptミニファイア、特にGoogle Closer Compilerの(いわゆる)シンプルモードの登場により、保存されたバイト数は現時点では無関係であると思います。
ブライアンフィールド

1
@webnesto構文のセマンティクスが同じ場合、構文によるパフォーマンスはありません。すぐにコードを実行するのではなく、最初にコードを解析してセマンティック分析を行います-ここで、両方の宣言スタイルが等しくなります。
エサイリヤ2013

14

ECMAScript6は、かなりうまく機能する破壊的な割り当てを導入しました:

[a, b] = [1, 2] a等しく1なり、b等しくなる2


質問の答えにはなりませんが、説明されている両方のアプローチのより良い代替案になる可能性があります。
svarog

1
変数の長いリストがある場合、あなたのアプローチは実際に実行可能ではないと思います。どの変数がどの変数に関連していて、エラーから保護されていないかを判断するのは難しいです。誤ったマージの際に、誤って配列から1つの要素を削除する可能性があります。例: let [aVar, bVar, cVar, xVar, yVar, zVar] = [10, 20, 30, 40, 50]; したがって、個人的にはお勧めしません。
キリル・レズニコフ2017年

1
同じ値で多くの変数を設定したい場合に便利です。たとえば、ループでゼロにリセットするために使用します。
Nick、

はい!これは私が探していたものです。特に、2次元のペアまたは多次元の値を定義したいが、配列は定義しない場合。
Eugene Kardash

11
var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;

より読みやすいです:

var variable1 = "Hello World!",
    variable2 = "Testing...",
    variable3 = 42;

しかし、彼らは同じことをします。


「ファイルスペース」の使用量を減らしますか?何か説明が必要だと思います。
Josh Stodola、

@JoshStodolaは私には同じファイルスペースを探します。以来var<space>、その<space><space><space><space>
WORMSS

@WORMSS、var<space>またはvar<tab>vsでない限り<tab>。まだ大部分は無意味です。
mpag

9

ES6 Destructuring割り当てを使用:配列の値またはオブジェクトのプロパティを個別の変数にアンパックします。

let [variable1 , variable2, variable3] = 
["Hello World!", "Testing...", 42];

console.log(variable1); // Hello World!
console.log(variable2); // Testing...
console.log(variable3); // 42


4
特に約10個の変数を割り当てる必要がある場合は、ひどい考えです。
Kirill Reznikov

7

私の唯一の、しかし本質的なコンマの使用法はforループ内にあります:

for (var i = 0, n = a.length; i < n; i++) {
  var e = a[i];
  console.log(e);
}

JavaScriptでこれが問題ないかどうかを調べるために、ここに行きました。

それが機能するのを見ても、nが関数に対してローカルであるかどうかという疑問が残りました。

これは、nがローカルであることを確認します。

a=[3,5,7,11];
(function l () { for (var i = 0, n = a.length; i < n; i++) {
  var e = a[i];
  console.log(e);
}}) ();
console.log(typeof n == "undefined" ?
  "as expected, n was local" : "oops, n was global");

少しの間、私は確信が持てませんでした。言語を切り替えました。


7

どちらも有効ですが、2番目を使用すると、経験の浅い開発者がvarステートメントをあちこちに配置して、巻き上げの問題を引き起こすことを防ぎます。関数の上部に関数ごとに1つの変数しかない場合は、コード全体をデバッグする方が簡単です。これは、変数が宣言されている行が一部の行ほど明確ではないことを意味します。

開発者が「var」を好きな場所にドロップするのをやめることを意味するのであれば、トレードオフはそれだけの価値があると思います。

人々はJSLintについて文句を言うかもしれませんが、私もそうですが、その多くは言語の問題を修正することではなく、コーダーの悪い習慣を正すことで、彼らが書くコードの問題を防ぐことに向けられています。したがって:

「ブロックスコープの言語では、通常、変数を最初に使用する場所で宣言することをお勧めします。ただし、JavaScriptにはブロックスコープがないため、関数のすべての変数を関数の上部で宣言する方が賢明です。関数ごとに単一のvarステートメントを使用することをお勧めします。」- http://www.jslint.com/lint.html#scope


6

それは個人的な好みの問題だと思います。私は次の方法でそれを行うことを好みます:

   var /* Vars */
            me = this, that = scope,
            temp, tempUri, tempUrl,
            videoId = getQueryString()["id"],
            host = location.protocol + '//' + location.host,
            baseUrl = "localhost",
            str = "Visit W3Schools",
            n = str.search(/w3schools/i),
            x = 5,
            y = 6,
            z = x + y
   /* End Vars */;

6

単一ステートメントのバージョン(単一のvar)を回避するもう1つの理由は、デバッグです。例外がスローされた場合の割り当て行、スタックトレースには1行のみが表示されます。

コンマ構文で定義された10個の変数がある場合、どの変数が原因であるかを直接知る方法はありません。

個々のステートメントのバージョンは、このあいまいさに悩まされることはありません。


2

「結合上の結合」の概念は、単なるオブジェクト/モジュール/関数よりも一般的に適用できます。この状況でも機能します。

OPが提案する2番目の例では、すべての変数を同じステートメントに結合しています。これにより、行の1つを取得して、何かを壊さずに別の場所に移動することができません(高結合)。彼の最初の例では、変数の割り当てを互いに独立させています(低結合)。

「低結合は、適切に構造化されたコンピューターシステムと優れた設計の兆候であることが多く、高い凝集性と組み合わせると、高い可読性と保守性の一般的な目標をサポートします。」

http://en.wikipedia.org/wiki/Coupling_(computer_programming)

だから最初のものを選択してください。


1
これが結合または凝集にどのように関連しているかはわかりません。詳しく説明しますか?
Edson Medina

OPが提案する2番目の例では、すべての変数を同じステートメントに結合しています。これにより、行の1つを取得して、ものを壊さずに別の場所に移動することができません(高結合)。彼の最初の例では、変数の割り当てを互いに独立させています(低結合)。
Magne、2015年

結合とは、コード行ではなく、さまざまなモジュール/オブジェクト/関数間の相互依存関係のことです!
Edson Medina

1
もともとはモジュールに関するものでしたが、独自のオブジェクト/関数の定義への組み込みが示すように、概念はより一般的に適用できます。
Magne

2

古い投稿ですが、Google社員の視点を少し追加します。

保守性の問題は、このような小さなフォーマットでかなり簡単に克服できます。

let
  my_var1 = 'foo',
  my_var2 = 'bar',
  my_var3 = 'baz'
;

私は個人的な好みの問題として、このフォーマットを厳密に使用しています。もちろん、この宣言は、単一の宣言の場合、または単純に作品を構成する場合はスキップします。


1

ES6の使用を開始する前は、単一のvar宣言を使用するアプローチは良くも悪くもなかったと思います(リンターとがある場合)'use strict'。これは本当に好みの好みでした。しかし、今は状況が変わりました。複数行宣言を支持する私の考えがあります。 :

  1. 現在、2種類の新しい変数があり、var廃止されました。const本当に必要になるまで、どこでも使用することをお勧めしますlet。そのため、コードの中央に代入を含む変数宣言がコードに含まれることがよくあります。また、ブロックスコープのため、小さな変更の場合は、ブロック間で変数を移動することがよくあります。複数行の宣言でそれを行う方が便利だと思います。

  2. ES6の構文はより多様になり、デストラクタ、テンプレート文字列、矢印関数、オプションの割り当てが追加されました。単一のvar宣言でそのすべての機能を多用すると、読みやすさが低下します。


0

私の意見では読むのが難しい(Knockoutを使用するアプリケーションからの)他の方法でそれが終わる可能性があるため、最初の方法(複数の変数)が最良であると思います。

    var categories = ko.observableArray(),
        keywordFilter = ko.observableArray(),
        omniFilter = ko.observable('').extend({ throttle: 300 }),
        filteredCategories = ko.computed(function () {
            var underlyingArray = categories();
            return ko.utils.arrayFilter(underlyingArray, function (n) {
                return n.FilteredSportCount() > 0;
            });
        }),
        favoriteSports = ko.computed(function () {
            var sports = ko.observableArray();
            ko.utils.arrayForEach(categories(), function (c) {
                ko.utils.arrayForEach(c.Sports(), function (a) {
                    if (a.IsFavorite()) {
                        sports.push(a);
                    }
                });
            });
            return sports;
        }),
        toggleFavorite = function (sport, userId) {
            var isFavorite = sport.IsFavorite();

            var url = setfavouritesurl;

            var data = {
                userId: userId,
                sportId: sport.Id(),
                isFavourite: !isFavorite
            };

            var callback = function () {
                sport.IsFavorite(!isFavorite);
            };

            jQuery.support.cors = true;
            jQuery.ajax({
                url: url,
                type: "GET",
                data: data,
                success: callback
            });
        },
        hasfavoriteSports = ko.computed(function () {
            var result = false;
            ko.utils.arrayForEach(categories(), function (c) {
                ko.utils.arrayForEach(c.Sports(), function (a) {
                    if (a.IsFavorite()) {
                        result = true;
                    }
                });
            });
            return result;
        });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.