Operator Ternary dalam JavaScript Tanpa "Lain-Lain"

149

Saya selalu harus memasukkan ke nulldalam kondisi lain yang tidak memiliki apa pun. Apakah ada pula di sekitarnya? Misalnya

condition ? x = true : null;

pada dasarnya, apakah ada cara untuk melakukannya:

condition ? x = true;

Sekarang muncul sebagai kesalahan sintaksis

FYI, berikut adalah beberapa contoh kode nyata:

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;
Oscar Godson
sumber
21
penggunaan seperti terner condition ? x = true : null;mungkin harus ditulis sebagai x = (condition ? true : null);. Sebagai tambahan, dalam javascript nullbernilai false sehingga dalam hal ini Anda bisa x = (condition);dan mencapai hasil yang sama.
Matt S
1
Matt, jawaban Anda yang terbaik, tapi itu bukan jawaban, itu komentar!
Cheeso
Matt, kode AKTUAL saya adalah:! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null; cara yang lebih pendek dan lebih baik untuk menulis itu?
Oscar Godson
2
defaults.slideshowWidth = defaults.slideshowWidth || obj.find ('img'). width () + 'px';
kennebec
akan lebih baik untuk menghindari penugasan identitas, jadi ini seharusnya hanya sebuah kondisi:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Mihail Malostanidis

Jawaban:

226

Pertama-tama, ekspresi ternary bukanlah pengganti untuk konstruksi if / else - yang setara dengan konstruksi if / else yang mengembalikan nilai. Yaitu, klausa if / else adalah kode, ekspresi ternary adalah ekspresi , yang berarti ia mengembalikan nilai.

Ini berarti beberapa hal:

  • gunakan ekspresi ternary hanya ketika Anda memiliki variabel di sisi kiri =yang akan diberi nilai kembali
  • hanya menggunakan ekspresi ternary ketika nilai yang dikembalikan adalah salah satu dari dua nilai (atau gunakan ekspresi bertingkat jika itu pas)
  • setiap bagian dari ekspresi (setelah? dan setelah:) harus mengembalikan nilai tanpa efek samping (ekspresi x = true mengembalikan true karena semua ekspresi mengembalikan nilai terakhir, tetapi juga mengubah x tanpa x memiliki efek pada nilai yang dikembalikan)

Singkatnya - penggunaan ekspresi terner yang "benar" adalah

var resultofexpression = conditionasboolean ? truepart: falsepart;

Alih-alih contoh Anda condition ? x=true : null ;, di mana Anda menggunakan ekspresi ternary untuk menetapkan nilai x, Anda bisa menggunakan ini:

 condition && (x = true);

Ini masih merupakan ekspresi dan karena itu mungkin tidak lulus validasi, jadi pendekatan yang lebih baik akan

 void(condition && x = true);

Yang terakhir akan lulus validasi.

Tetapi sekali lagi, jika nilai yang diharapkan adalah boolean, cukup gunakan hasil dari ekspresi kondisi itu sendiri

var x = (condition); // var x = (foo == "bar");

PEMBARUAN Terkait sampel Anda, ini mungkin lebih tepat:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';
Sean Kinsey
sumber
4
SO brilian, tidak memungkinkan edit untuk memperbaiki i/elsekesalahan ketik karena tidak cukup karakter.
dewd
1
batal (kondisi && x = true) - ini tampak hebat tetapi tampaknya melempar kesalahan "penugasan sisi kiri yang tidak valid"
Eugene Tiurin
1
void (condition && (x = true)) // membuat penugasan terpisah dari nilai pertama
diamondsea
4
Namun, ini tidak intuitif untuk dibaca, terutama untuk pengembang yang tidak terbiasa dengan gaya ini. Anda dapat dengan mudah dan lebih mudah menulis ini sebagai: if (kondisi) {x = true; }
diamondsea
2
Bisakah Anda menjelaskan apa yang Anda maksud dengan "mungkin tidak lulus validasi"? Saya tidak mengerti mengapa orang harus membungkus ekspresi void(). Terima kasih.
gilad mayani
20

Tidak, itu membutuhkan tiga operan. Itu sebabnya mereka disebut operator ternary .

Namun, untuk apa yang Anda miliki sebagai contoh, Anda dapat melakukan ini:

if(condition) x = true;

Meskipun lebih aman untuk memiliki kawat gigi jika Anda perlu menambahkan lebih dari satu pernyataan di masa depan:

if(condition) { x = true; }

Sunting: Sekarang Anda menyebutkan kode aktual di mana pertanyaan Anda berlaku untuk:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }
Dalam silico
sumber
1
Anda bisa, tetapi seharusnya tidak. Atleast bukan tanpa kurung keriting di sekitarnya - itu sangat kesalahan.
Konerak
1
Benarkah itu? Saya mengerti alasan utama untuk membutuhkan ikal adalah karena mereka membuat hidup jslint lebih mudah.
Cheeso
@Cheeso itu kesalahan dalam arti refactoring. Anda kembali untuk menambahkan lebih banyak untuk dilakukan dalam kasus kondisi yang sebenarnya tanpa menyadari tidak ada kurung kurawal di sana. Kode baru akan selalu dieksekusi daripada ketika true.
Matt S
Tidak saya tahu, saya hanya suka menulis conditional tanpa tambahan seperti if () {} else {} ketika itu sama dengan hanya?:;
Oscar Godson
3
Jujur, saya tidak pernah tahu pengembang lebih takut menggunakan bahasa daripada Javascript: -PI tidak akan suka seseorang mengatakan kepada saya bahwa saya seharusnya tidak menggunakan kurung kurawal. Saya sering menghilangkan mereka dan tidak pernah memiliki masalah lebih dari yang saya tidak sengaja kehilangan penjepit.
Andy E
12

Lebih sering orang menggunakan operator logis untuk mempersingkat sintaks pernyataan:

!defaults.slideshowWidth &&
  (defaults.slideshowWidth = obj.find('img').width()+'px');

Tetapi dalam kasus khusus Anda, sintaksinya bisa lebih sederhana

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Kode ini akan mengembalikan defaults.slideshowWidthnilai jika defaults.slideshowWidthdievaluasi ke true dan obj.find('img').width()+'px'nilai sebaliknya.

Lihat Evaluasi Sirkuit Pendek dari operator logis untuk detailnya.

Eugene Tiurin
sumber
11
var x = condition || null;
philfreo
sumber
2
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')ataudefaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
Casey Chu
> Mengembalikan expr1 jika dapat dikonversi ke true; jika tidak, kembalikan expr2. Logical Operators (MDN)
Szabolcs Páll
5

Anda bisa menulis

x = condition ? true : x;

Sehingga x tidak dimodifikasi ketika kondisinya salah.

Ini kemudian setara dengan

if (condition) x = true

EDIT:

!defaults.slideshowWidth 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : null 

Ada beberapa alternatif - saya tidak mengatakan ini lebih baik / lebih buruk - hanya alternatif

Melewati nol sebagai parameter ketiga berfungsi karena nilai yang ada adalah nol. Jika Anda refactor dan mengubah kondisinya, maka ada bahaya bahwa ini tidak lagi benar. Melewati nilai yang ada sebagai pilihan ke-2 dalam penjaga ternary terhadap hal ini:

!defaults.slideshowWidth = 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : defaults.slideshowwidth 

Lebih aman, tapi mungkin tidak sebaik untuk dilihat, dan lebih banyak mengetik. Dalam praktiknya, saya mungkin akan menulis

defaults.slideshowWidth = defaults.slideshowWidth 
               || obj.find('img').width()+'px'
mdma
sumber
Beberapa kode langsung adalah (lagian untuk menghilangkan nol dalam ini?):! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null;
Oscar Godson
2

Dalam kasus Anda, saya melihat operator ternary sebagai mubazir. Anda bisa menetapkan variabel langsung ke ekspresi, menggunakan operator ||, &&.

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;

akan menjadi :

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Lebih jelas, lebih gaya "javascript".

Krasimir Kirilov
sumber
2

Bagaimana dengan sederhana

    if (condition) { code if condition = true };
Yandiro
sumber
1

Untuk menggunakan Operator Ternary tanpa yang lain di dalam deklarasi array atau objek, Anda dapat menggunakan operator spread ES6 ...()

const cond = false;
const arr = [
  ...(cond ? ['a'] : []),
  'b',
];
    // ['b']

Dan untuk benda:

const cond = false;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
    // {b: 2}

sumber asli

kabut
sumber