面白いツイートから始めましょう:

末尾の「c」はコンマ演算子です。 重要な演算子のリストの最後で、ほとんど文書化されていませんが、非常に便利です。 それはそれほど一般的ではありませんが、私は本当にそれが好きです。 彼女はシンプルでエレガントで、彼女と良い関係にある方が良いです。
彼女は何をしているの?
コンマ演算子は両方のオペランドを(左から右に)実行し、2番目の演算子の値を返します。 ( MDC )
var a = (7, 5); a; //5 var x, y, z x = (y=1, z=4); x; //4 y; //1 z; //4
あなたの例ではなぜ変数の割り当てが括弧で囲まれているのですか?
オペレーターの優先順位のため。 JavaScript式には、いくつかの異なる演算子を含めることができます。 次の式には3つの演算子(* + and、)が含まれています。
return 5 * 2 + 3, 22;
演算子の優先順位は、式内でオペランドが実行される順序を決定します。
演算子の全リストはこちら 。 コンマ演算子は、すべての演算子の中で最も低い優先度を持っています。 例を見てみましょう:
//original return 5 * 2 + 3, 22; //apply * operator return 10 + 3, 22; //apply + operator return 13, 22; //apply , operator return 22;
括弧を削除するとどうなるか見てみましょう。
//original var a = 7, 5; //apply = operator var a, 5; //a is now 7 //SyntaxError: missing variable name
括弧で式をフレーミングし、最高の優先度を持つグループを作成します。
これにより、カンマ演算子が最初に適用されます。
//original var a = (7, 5); //apply group var a = 5;
実際には、優先順位が低いため、コンマは強力なツールです。 実際、彼女は通訳者に次のように伝えます。まず、私の周りの他のすべてのオペレーターが何をしているかを見てから、結果を美化します。
一部の式には複数のコンマが含まれます。 どのように機能しますか?
チェーン内の各演算子は、左から右に順番に処理されます。
var a = (1, 2, 3, 4); a; //4
これは次と同等です:
var a = (((1, 2), 3), 4); a; //4
型リテラルと宣言で使用されるコンマはどうですか?
これらの区切り文字は、実際にはコンマ演算子ではありません。 コンマ区切り文字の目的は、リスト内のメンバーを分離することです。 例:
// 4 var arr = [1, 2, 3, 4]; // var obj = { a: 22, f: function() {return this.a*this.a} } // var a = 1, b = 2, c = 3; // , 2 Math.max(4, 7);
コンマ演算子を使用する理由
次に、JavaScriptが1つだけを想定している場所で複数の式を実行できるようにします。 コンマ演算子を使用した式はそれほど一般的ではなく、めったに重要ではありませんが、非常にエレガントです。
var r = [], n = 0, a = 0, b = 1, next; function nextFibonacci() { next = a + b; return b = (a = b, next); // <<< } while(n++ < 10) { r.push(nextFibonacci()); } r; //[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
function getRandomPrime() { while(n = Math.round(Math.random()*1000000000), !isPrime(n)); // <<< return n; } var isPrime = function(n) { d = Math.ceil(Math.sqrt(n)); while(n%(d--) && d); return !d; } getRandomPrime(); //425593109 getRandomPrime(); //268274719
セミコロンはマスクされたコンマではありませんか?
セミコロンは宣言の区切り記号であり、コンマは宣言内の式の区切り記号です。
&&演算子を使用して複数の式を順番に実行してみませんか?
コンマ演算子は、&&および||演算子に非常に近いです。 これらのステートメントはすべて、最後に実行した式を返します。 違いは次のとおりです。
LHE-左式
RHE-正しい表現
LHE && RHE
1.常にLHEを実行します
2. LHEがtrueの場合、RHEを実行します
LHE || レー
1.常にLHEを実行します
2. LHEがfalseの場合、RHEを実行します
LHE、RHE
1.常にLHEを実行します
2.常にRHEを実行します
両方の式を実行する必要がある場合は、コンマを選択する必要があります。
例はどうですか?
前述したように、コンマ演算子を使用すると、JavaScriptが1つだけを想定している場所で複数の式を実行できます。
forループ
以下は、コンマ演算子も使用するフィボナッチ数ジェネレータの代替バージョンです。
for ( var i=2, r=[0,1]; i<15; r.push(r[i-1] + r[i-2]), i++ ); r //"0,1,1,2,3,5,8,13,21,34,55,89,144,233,377"
別の例として、売り手が買い手の変化を構成する紙幣と硬貨を選択するのに役立つユーティリティを考えます。
function toCurrency(total, values) { total *= 100; for( var i=0,counts=[]; counts[i]=total/values[i], total=total%values[i]; // i++ ); return counts.map(Math.floor); } toCurrency(32.47, [500, 100, 25, 10, 5, 1]); //[6, 2, 1, 2, 0, 2]
同じユーティリティですが、フォーマットは次のとおりです。
function toCurrency(total, values, sym) { total *= 100; //do the calc for( var i=0,counts=[]; counts[i]=total/values[i], total=total%values[i]; // i++ ); //format var results = counts.map(function(s,i) { return s>=1 && [Math.floor(s),"x",(sym || '$') + (values[i]/100).toFixed(2)].join(' '); }); return results.filter(Boolean).join(', '); } toCurrency(19.77, [500,100,25,10,5,1]); //"3 x $5.00, 4 x $1.00, 3 x $0.25, 2 x $0.01" toCurrency(19.77, [500,100,50,20,10,5,1], '£'); //"3 x £5.00, 4 x £1.00, 1 x £0.50, 1 x £0.20, 1 x £0.05, 2 x £0.01" toCurrency(19.77, [500,100,50,20,10,5,2,1], '€'); //"3 x €5.00, 4 x €1.00, 1 x €0.50, 1 x €0.20, 1 x €0.05, 1 x €0.02"
次の関数は、カンマを使用して、ループ内の2つの変数を同時に増減させます。 出力は曲線です:
function renderCurve() { for(var a = 1, b = 10; a*b; a++, b--) // console.log(new Array(a*b).join('*')); } renderCurve(); /* ********* ***************** *********************** *************************** ***************************** ***************************** *************************** *********************** ***************** ********* */
whileループ
カンマ演算子を使用して、do-whileループの短いバージョンを作成できます。
この関数は、tagName(jQuery親に類似)という名前の要素のリストから祖先を検索します。
function firstAncestor(el, tagName) { while(el = el.parentNode, el && (el.tagName != tagName.toUpperCase())); return el; } //element in http://ecma262-5.com/ELS5_HTML.htm var a = $('Section_15.1.1.2'); firstAncestor(a, 'div'); //<div class="page">
三項演算子
三項演算子では、1つの式のみを実行できます。 複数の式を実行する必要がある場合は、if elseに切り替える必要があります。 コンマ演算子は、短い式を組み合わせるために使用すると読みやすくなります。
//player loses lives ? (gameOver(), exit()) : (lives--, go());
デバッグする
カンマ演算子を使用すると、コードを変更せずにconsole.logをどこにでも埋め込むことができます。
// products i > n var i=10, n=0, total=0; while(console.log(i,n), i-- > n++); { total += i*n }
// var arr = [1,2,3]; for ( var i=0, total=0; i<arr.length; console.log(i,total), total += arr[i++]); )
// 4 var testArray = [3, 5, 8, 4], total = 0; var plusFour = testArray.map(function(e) {e + 4}) plusFour.forEach(function(n) {console.log(n), isNaN(n) || (total += n)});
反復子バインディング
@wavdedは、コンマを使用する1つの方法を投稿しました。
var colorIndex = 0, colors = ["FF0000", "008000", "FF0086", "A2FF00", "0000FF", "800080"]; function selectNextColor(){ return colors[colorIndex++] || colors[colorIndex = 0, colorIndex++]; }
evalの間接呼び出し
eval 1は、呼び出されたコンテキストを使用します。 したがって、ループ内でevalを呼び出しても同じ結果が得られるという保証はありません。
kangax は 、コンマ演算子を使用して間接的にevalを呼び出すことができると書いています。これは常にグローバルコンテキスト2で呼び出されます。
var a = {}; (function() { eval("this.alert('If you can read this I must be global!')"); }).call(a); //TypeError: this.alert is not a function (function() { (0,eval)("this.alert('If you can read this I must be global!')"); }).call(a); //alerts: 'If you can read this I must be global!'
1. holivarovなしで、evalが悪であることを誰もが知っています。
2. ES5規格では、evalへの非直接呼び出しはすべてグローバルコンテキストを使用し、
ただし、すべてのブラウザがこのルールをサポートしているわけではありません(IE <= 8)
おわりに
コンマ演算子を使用せずに素晴らしいコードを書くことができます。 これは私があなたの時間を過ごしたことを意味しますか? しないことを望みます。 豊富な語彙により、作家や講演者はより専門的になり、言語の幅広い可能性にアクセスできるため、より優れたコーダーを作成できます。 メソッドが多くなればなるほど、より美しく、正確で読みやすいコードを書くことができます。 コンマ演算子を使って頑張って、使用例を共有してください!
読む
ECMA-262第5版
11.14コンマ演算子
10.4.2評価コードの入力
15.1.2.1.1 Evalへの直接呼び出し
Mozilla開発者センター
コンマ演算子
演算子の優先順位
Juriy Zaytsev( kangax ): グローバル評価、オプションは何 ですか
Mark Harter(@wavded): コンマ演算子を使用して配列を循環する
UPDは考慮に入れ、翻訳の欠陥を修正しました