JavaScriptによる複数の左側の割り当て


186
var var1 = 1,
    var2 = 1,
    var3 = 1;

これはこれと同等です:

var var1 = var2 = var3 = 1;

これは変数が定義されている順序であるとかなり確信しています:var3、var2、var1、これはこれと同等です:

var var3 = 1, var2 = var3, var1 = var2;

JavaScriptでこれを確認する方法はありますか?おそらくプロファイラーを使用していますか?



これは私が使用する場合にも適用されますthis.var1 = this.var2 = this.var3 = 1か?
Gangadhar JANNU 2018年

回答:


404

実は

var var1 = 1, var2 = 1, var3 = 1;

以下と同等ではありません

var var1 = var2 = var3 = 1;

違いはスコープの違いです。

function good() {
  var var1 = 1, var2 = 1, var3 = 1;
}

function bad() {
  var var1 = var2 = var3 = 1;
}

good();
console.log(window.var2); // undefined

bad();
console.log(window.var2); // 1. Aggh!

実際、これは割り当てが正しい連想であることを示しています。このbad例は次と同等です。

var var1 = (window.var2 = (window.var3 = 1));

44
ダン、それは予想外です。ヒントをありがとう、私はそのことに気をつけます。
David Calhoun、

10
右から左なので@ SkinnyG33k。そのため、左端より先に右端が解析されます。ので、その後var var1=var2発生します。それは似ていますvar3 = 1var2 = var3var3=1; var2=var3; var var1=var2
gcb

12
注:この種のことを事前に行いたいことがわかっている場合でも、割り当てから定義を分割することができます。だから:var v1, v2, v3;その後、後で:v1 = v2 = v3 = 6;それらはまだローカルスコープにあります。:ダビデは予想通り、これは(前var'd場合)仕事と警告を述べたのでalert(v1 = v2 = v3 = 6);
ShawnFumo

3
丁度。しかし、いくつかの一般的なベストプラクティスに従っている場合、この場合は変数を先頭に宣言することで、不要なミスを防ぎ、ローカル変数がグローバルスコープに漏れることを回避できます。参照:jsfiddle.net/gleezer/r9Mu8/1
のび太

1
「ダン、それは予想外だ」なぜこれは予期しないことでしょうか?ほとんどの言語では、使用する前に変数を宣言する必要があります。JavaScriptも同じです。変数の宣言を怠ると、デフォルトでグローバルウィンドウオブジェクトになります。JavaScriptで「use strict」を使用し始めると、より優れたJavaScriptプログラマになります。
チェンバレン2015年

19

JavaScriptでの割り当ては右から左に機能します。var var1 = var2 = var3 = 1;

これらの変数のいずれかの値が1このステートメントの後にある場合、論理的には右から始まっている必要があります。そうでない場合、値or var1およびand var2は未定義になります。

これvar var1 = (var2 = (var3 = 1));は、最も内側の括弧のセットが最初に評価される場所と同等と考えることができます。


1
ありがとう、これは間違いなく役立ちます。右から左以外で評価された場合にどのエラーがスローされるかを考えると役立ちます(この場合、エラーはvar1 / var2が未定義であることです)。
David Calhoun、

5
これは実際には構文エラーです。(直後は持てませんvar。括弧の外側のセットを削除すると、エラーなしでコンパイルできますvar var1 = (var2 = (var3 = 1));。当時はあまり意味がわからなかったと感じていましたが、同じことだと思います。
ジャスティンジョンソン

var var1 = var2 = var3 = 1;. 等しい var var3 = 1; var var2 = var3; var var1 = var2;
xgqfrms

8

var var1 = 1、var2 = 1、var3 = 1;

この場合、 varキーワードは3つの変数すべてに適用できます。

var var1 = 1,
    var2 = 1,
    var3 = 1;

これはこれと同等ではありません:

var var1 = var2 = var3 = 1;

この場合、screens varキーワードはvar1変数の巻き上げにのみ適用され、式の残りの部分は正常に評価されるため、変数var2, var3グローバルになります。

JavaScriptはこのコードを次の順序で処理します。

/*
var 1 is local to the particular scope because of var keyword
var2 and var3 will become globals because they've used without var keyword
*/

var var1;   //only variable declarations will be hoisted.

var1= var2= var3 = 1; 

8
a = (b = 'string is truthy'); // b gets string; a gets b, which is a primitive (copy)
a = (b = { c: 'yes' }); // they point to the same object; a === b (not a copy)

(a && b)論理的である(a ? b : a)との乗算のように振る舞う(例えば。!!a * !!b

(a || b)論理的である(a ? a : b)(例えば。ほかのようにして振る舞います!!a + !!b

(a = 0, b)a真実である場合、気にしないことを意味し、暗黙的に戻りますb


a = (b = 0) && "nope, but a is 0 and b is 0"; // b is falsey + order of operations
a = (b = "b is this string") && "a gets this string"; // b is truthy + order of ops

JavaScript演算子の優先順位(操作の順序)

コンマ演算子は実際には最も特権の少ない演算子ですが、括弧は最も特権が高い演算子であり、1行の式を作成する場合は括弧が密接に関係していることに注意してください。


最終的には、ハードコードされた値ではなく「サンク」が必要になる場合があります。私にとって、サンクは関数と結果の値(同じ「もの」)の両方です。

const windowInnerHeight = () => 0.8 * window.innerHeight; // a thunk

windowInnerHeight(); // a thunk

4

これを試して:

var var1=42;
var var2;

alert(var2 = var1); //show result of assignment expression is assigned value
alert(var2); // show assignment did occur.

最初のアラートの単一の「=」に注意してください。これは、割り当て式の結果が割り当てられた値であることを示し、2番目のアラートは割り当てが行われたことを示します。

論理的には、割り当ては右から左にチェーンされている必要があります。ただし、これはすべてJavaScriptに対してアトミックであるため(スレッド化がないため)、特定のエンジンが実際には少し異なる方法で最適化することを選択する場合があります。


1
答えてくれてありがとう。複数割り当て構造(a = b = c)を維持しながらアラートを使用する方法を探していたと思いますが、それは可能ではないと思います。
David Calhoun、

1
JavaScriptのような個々のステートメント(およびいくつかの式はすべて1つのステートメントで機能する)は、アトミックと見なすことができます。あなたはそれを分割する必要があるでしょう。
Joel Coehoorn、2009年

1

それらが同じではないことは、今では明らかです。それをコーディングする方法は

var var1, var2, var3
var1 = var2 = var3 = 1

そして、割り当てについてはどうですか?varとまったく同じですが、ブロックスコープのためにlet割り当てで混乱させないでください。

let var1 = var2 = 1 // here var2 belong to the global scope

次のことができます。

let v1, v2, v3
v1 = v2 = v3 = 2

注:ところで、同じ行で複数の宣言を使用することも、複数の割り当てを使用することはお勧めしません。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.