web-dev-qa-db-ja.com

JavaScriptを使用した複数の左手割り当て

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

これはこれと同等です:

var var1 = var2 = var3 = 1;

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

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

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

174
David Calhoun

実際、

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

notと同等:

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));
382
Crescent Fresh

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

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

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

17
Justin Johnson
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
8
neaumusic

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

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

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

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

var var1 = var2 = var3 = 1;

この場合、画面の背後でvarキーワードは変数の巻き上げのためvar1にのみ適用され、式の残りの部分は正常に評価されるため、変数var2, var3globalsになります=

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; 
7
Gangadhar Jannu

これを試して:

var var1=42;
var var2;

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

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

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

4
Joel Coehoorn

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

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

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

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

次のことができます。

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

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

0
fenderOne