Saya membaca ini pertanyaan tentang "koma operator" dalam ekspresi ( ,
) dan docs MDN tentang hal itu, tapi aku tidak bisa memikirkan sebuah skenario di mana hal ini berguna.
Jadi, kapan operator koma berguna?
,
operator. Baris itu juga valid C#
, tetapi ,
operatornya tidak ada di sana.
,
tidak selalu ,
operator (dan tidak pernah menjadi ,
operator di C #). Jadi C # bisa kekurangan ,
operator sementara masih bebas menggunakan ,
sebagai bagian dari sintaks.
,
tidak banyak digunakan (dan tidak setiap kemunculan a ,
adalah operator koma) . Tetapi Anda dapat meminjamnya dan Array untuk melakukan pertukaran variabel secara inline tanpa membuat variabel sementara. Mengingat Anda ingin menukar nilai a
dan b
, Anda bisa melakukannya a = [b][b = a,0]
. Ini menempatkan arus b
di Array. Yang kedua []
adalah notasi akses properti. Indeks yang diakses adalah 0
, tetapi tidak sebelum ditetapkan a
ke b
, yang sekarang aman karena b
disimpan di Array. yang ,
memungkinkan kita melakukan beberapa ekspresi di []
.
Jawaban:
Berikut ini mungkin tidak terlalu berguna karena Anda tidak menulisnya sendiri, tetapi minifier dapat menyusutkan kode menggunakan operator koma. Sebagai contoh:
if(x){foo();return bar()}else{return 1}
akan menjadi:
return x?(foo(),bar()):1
The ? :
operator dapat digunakan sekarang, karena operator koma (sampai batas tertentu) memungkinkan untuk dua pernyataan yang akan ditulis sebagai satu pernyataan.
Ini adalah berguna dalam yang memungkinkan untuk beberapa kompresi rapi (39 -> 24 byte di sini).
Saya ingin menekankan fakta bahwa koma di var a, b
adalah tidak operator koma karena tidak ada dalam suatu ekspresi . Koma memiliki arti khusus dalam var
pernyataan . a, b
dalam sebuah ekspresi akan mengacu pada dua variabel dan mengevaluasi b
, yang bukan kasusnya var a, b
.
if (condition) var1 = val1, var2 = val2;
Saya pribadi berpikir menghindari tanda kurung jika memungkinkan membuat kode lebih mudah dibaca.
Operator koma memungkinkan Anda meletakkan beberapa ekspresi di tempat yang diharapkan satu ekspresi. Nilai yang dihasilkan dari beberapa ekspresi yang dipisahkan dengan koma akan menjadi nilai ekspresi yang dipisahkan koma terakhir.
Saya pribadi tidak terlalu sering menggunakannya karena tidak banyak situasi di mana lebih dari satu ekspresi diharapkan dan tidak ada cara yang kurang membingungkan untuk menulis kode daripada menggunakan operator koma. Satu kemungkinan menarik adalah di akhir for
pengulangan ketika Anda ingin lebih dari satu variabel bertambah:
// j is initialized to some other value
// as the for loop executes both i and j are incremented
// because the comma operator allows two statements to be put in place of one
for (var i = 0; i < items.len; i++, j++) {
// loop code here that operates on items[i]
// and sometimes uses j to access a different array
}
Di sini Anda melihat bahwa i++, j++
dapat diletakkan di tempat di mana satu ekspresi diperbolehkan. Dalam kasus khusus ini, beberapa ekspresi digunakan untuk efek samping sehingga tidak masalah bahwa ekspresi gabungan mengambil nilai yang terakhir, tetapi ada kasus lain di mana hal itu mungkin benar-benar penting.
Operator Koma sering kali berguna saat menulis kode fungsional dalam Javascript.
Pertimbangkan kode ini yang saya tulis untuk SPA beberapa waktu lalu yang memiliki sesuatu seperti berikut
const actions = _.chain(options)
.pairs() // 1
.filter(selectActions) // 2
.map(createActionPromise) // 3
.reduce((state, pair) => (state[pair[0]] = pair[1], state), {}) // 4
.value();
Ini adalah skenario yang cukup kompleks, tetapi dunia nyata. Bersabarlah sementara saya menjelaskan apa yang terjadi, dan dalam prosesnya buat kasus untuk Operator Koma.
Bongkar semua opsi yang diteruskan ke fungsi ini menggunakan pairs
yang akan berubah { a: 1, b: 2}
menjadi[['a', 1], ['b', 2]]
Larik pasangan properti ini difilter oleh pasangan mana yang dianggap sebagai 'tindakan' dalam sistem.
Kemudian indeks kedua dalam larik diganti dengan fungsi yang mengembalikan janji yang mewakili tindakan itu (menggunakan map
)
Akhirnya panggilan ke reduce
akan menggabungkan setiap "array properti" ( ['a', 1]
) kembali menjadi objek akhir.
Hasil akhirnya adalah versi options
argumen yang diubah , yang hanya berisi kunci yang sesuai dan nilainya dapat dikonsumsi oleh fungsi pemanggil.
Lihat saja
.reduce((state, pair) => (state[pair[0]] = pair[1], state), {})
Anda dapat melihat fungsi pengurangan dimulai dengan objek status kosong state
, dan untuk setiap pasangan yang mewakili kunci dan nilai, fungsi mengembalikan state
objek yang sama setelah menambahkan properti ke objek yang sesuai dengan pasangan kunci / nilai. Karena sintaks fungsi panah ECMAScript 2015, badan fungsi adalah ekspresi, dan sebagai hasilnya, Operator Koma memungkinkan fungsi "iterasi" yang ringkas dan berguna .
Secara pribadi saya telah menemukan banyak kasus saat menulis Javascript dengan gaya yang lebih fungsional dengan ECMAScript 2015 + Fungsi Panah. Karena itu, sebelum menemukan fungsi panah (seperti pada saat penulisan pertanyaan), saya tidak pernah menggunakan operator koma dengan cara yang disengaja.
reduce
.reduce((state, [key, value]) => (state[key] = value, state), {})
. Dan saya menyadari ini mengalahkan tujuan jawaban tetapi .reduce((state, [key, value]) => Object.assign(state, { [key]: value }), {})
akan menghilangkan kebutuhan akan operator koma sepenuhnya.
Penggunaan lain dari operator koma adalah untuk menyembunyikan hasil yang tidak Anda pedulikan di repl atau konsol, semata-mata untuk kenyamanan.
Misalnya, jika Anda mengevaluasi myVariable = aWholeLotOfText
di repl atau konsol, ini akan mencetak semua data yang baru saja Anda tetapkan. Ini mungkin halaman dan halaman, dan jika Anda memilih untuk tidak melihatnya, Anda dapat mengevaluasi myVariable = aWholeLotOfText, 'done'
, dan repl / console akan mencetak 'selesai'.
Oriel dengan benar menunjukkan † bahwa kustomisasi toString()
atau get()
fungsi bahkan dapat membuat ini berguna.
Operator koma tidak khusus untuk JavaScript, ini tersedia dalam bahasa lain seperti C dan C ++ . Sebagai operator biner, ini berguna ketika operan pertama, yang umumnya merupakan ekspresi, memiliki efek samping yang diinginkan yang dibutuhkan oleh operan kedua. Salah satu contoh dari wikipedia:
i = a += 2, a + b;
Jelas Anda dapat menulis dua baris kode yang berbeda, tetapi menggunakan koma adalah pilihan lain dan terkadang lebih mudah dibaca.
Saya tidak setuju dengan Flanagan, dan mengatakan, koma itu sangat berguna dan memungkinkan untuk menulis kode yang lebih mudah dibaca dan elegan, terutama ketika Anda tahu apa yang Anda lakukan:
Berikut artikel yang sangat mendetail tentang penggunaan koma:
Beberapa contoh dari luar sana untuk bukti demonstrasi:
function renderCurve() {
for(var a = 1, b = 10; a*b; a++, b--) {
console.log(new Array(a*b).join('*'));
}
}
Generator fibonacci:
for (
var i=2, r=[0,1];
i<15;
r.push(r[i-1] + r[i-2]), i++
);
// 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377
Temukan elemen induk pertama, analog dari .parent()
fungsi 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">
while ((el = el.parentNode) && (el.tagName != tagName.toUpperCase()))
akan baik-baik saja dalam konteks itu.
Saya belum menemukan penggunaan praktisnya selain itu tetapi di sini adalah satu skenario di mana James Padolsey dengan baik menggunakan teknik ini untuk deteksi IE dalam loop sementara:
var ie = (function(){
var undef,
v = 3,
div = document.createElement('div'),
all = div.getElementsByTagName('i');
while ( // <-- notice no while body here
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
}());
Kedua baris ini harus dijalankan:
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
Dan di dalam operator koma, keduanya dievaluasi meskipun seseorang dapat membuatnya menjadi pernyataan terpisah.
do
- while
loop.
Ada sesuatu yang "aneh" yang bisa dilakukan dalam JavaScript memanggil suatu fungsi secara tidak langsung dengan menggunakan operator koma.
Ada penjelasan panjang di sini: Pemanggilan fungsi tidak langsung dalam JavaScript
Dengan menggunakan sintaks ini:
(function() {
"use strict";
var global = (function () { return this || (1,eval)("this"); })();
console.log('Global === window should be true: ', global === window);
var not_global = (function () { return this })();
console.log('not_global === window should be false: ', not_global === window);
}());
Anda bisa mendapatkan akses ke variabel global karena eval
berfungsi secara berbeda saat dipanggil secara langsung vs tidak langsung.
Saya telah menemukan operator koma paling berguna saat menulis pembantu seperti ini.
const stopPropagation = event => (event.stopPropagation(), event);
const preventDefault = event => (event.preventDefault(), event);
const both = compose(stopPropagation, preventDefault);
Kamu bisa mengganti koma dengan || atau &&, tetapi Anda harus mengetahui apa yang dikembalikan fungsi tersebut.
Lebih penting dari itu, pemisah koma mengkomunikasikan maksud - kode tidak peduli apa yang mengevaluasi operan kiri, sedangkan alternatif mungkin memiliki alasan lain untuk berada di sana. Ini pada gilirannya membuatnya lebih mudah untuk dipahami dan difaktor ulang. Jika tipe kembalian fungsi pernah berubah, kode di atas tidak akan terpengaruh.
Secara alami Anda dapat mencapai hal yang sama dengan cara lain, tetapi tidak sesingkat itu. Jika || dan && menemukan tempat yang umum digunakan, begitu juga operator koma.
tap
( ramdajs.com/docs/#tap ). Pada dasarnya, Anda sedang menjalankan efek samping dan kemudian mengembalikan nilai awal; sangat berguna dalam pemrograman fungsional :)
Satu kasus khas yang akhirnya saya gunakan adalah selama penguraian argumen opsional. Saya pikir itu membuatnya lebih mudah dibaca dan lebih ringkas sehingga parsing argumen tidak mendominasi badan fungsi.
/**
* @param {string} [str]
* @param {object} [obj]
* @param {Date} [date]
*/
function f(str, obj, date) {
// handle optional arguments
if (typeof str !== "string") date = obj, obj = str, str = "default";
if (obj instanceof Date) date = obj, obj = {};
if (!(date instanceof Date)) date = new Date();
// ...
}
Katakanlah Anda memiliki array:
arr = [];
Saat Anda push
masuk ke dalam array itu, Anda jarang tertarik dengan push
nilai yang dikembalikan, yaitu panjang baru dari array tersebut, melainkan array itu sendiri:
arr.push('foo') // ['foo'] seems more interesting than 1
Dengan menggunakan operator koma, kita dapat mendorong ke array, menentukan array sebagai operan terakhir untuk koma, dan kemudian menggunakan hasilnya - array itu sendiri - untuk panggilan metode array berikutnya, semacam rangkaian:
(arr.push('bar'), arr.push('baz'), arr).sort(); // [ 'bar', 'baz', 'foo' ]
Area lain di mana operator koma dapat digunakan adalah Kode Obfuscation .
Katakanlah seorang pengembang menulis beberapa kode seperti ini:
var foo = 'bar';
Sekarang, dia memutuskan untuk mengaburkan kode tersebut. Alat yang digunakan dapat mengubah kode seperti ini:
var Z0b=(45,87)>(195,3)?'bar':(54,65)>(1,0)?'':'baz';// Z0b == 'bar'
var i, j, k;
vsvar i; var j, var k
?