Saya ingin membuat objek dengan anggota ditambahkan kondisional. Pendekatan sederhana adalah:
var a = {};
if (someCondition)
a.b = 5;
Sekarang, saya ingin menulis kode yang lebih idiomatis. Aku sedang mencoba:
a = {
b: (someCondition? 5 : undefined)
};
Tapi sekarang, b
adalah anggota a
yang nilainya undefined
. Ini bukan hasil yang diinginkan.
Apakah ada solusi praktis?
Memperbarui
Saya mencari solusi yang dapat menangani kasus umum dengan beberapa anggota.
a = {
b: (conditionB? 5 : undefined),
c: (conditionC? 5 : undefined),
d: (conditionD? 5 : undefined),
e: (conditionE? 5 : undefined),
f: (conditionF? 5 : undefined),
g: (conditionG? 5 : undefined),
};
javascript
Viebel
sumber
sumber
a.b
, mengambila.b
kembali akanundefined
tetap.in
operator digunakan.Jawaban:
Dalam Javascript murni, saya tidak bisa memikirkan hal yang lebih idiomatis daripada cuplikan kode pertama Anda.
Namun, jika menggunakan perpustakaan jQuery tidak keluar dari pertanyaan, maka $ .extend () harus memenuhi persyaratan Anda karena, seperti yang dikatakan dalam dokumentasi:
Karena itu, Anda dapat menulis:
Dan dapatkan hasil yang Anda harapkan (jika
conditionB
adafalse
, makab
tidak akan ada dalama
).sumber
Saya pikir @InspiredJW melakukannya dengan ES5, dan seperti yang ditunjukkan @trincot, menggunakan es6 adalah pendekatan yang lebih baik. Tetapi kita dapat menambahkan sedikit lebih banyak gula, dengan menggunakan operator penyebaran, dan evaluasi hubungan pendek DAN logis:
sumber
Null/Undefined Are Ignored
, tidak dikatakanfalse
diabaikan. Transponder dapat memungkinkan hal ini sampai saat ini, tetapi apakah itu sesuai? Berikut ini seharusnya{...someCondition ? {b: 5} : null}
tetapi tidak kompak.Object.assign
dan memiliki prioritas lebih rendah dari operator &&. Ini mengabaikan nilai tanpa properti (boolean, null, undefined, number), dan menambahkan semua properti objek setelah...
di tempat. ingat&&
operator mengembalikan nilai yang benar jika benar, atau salah jika sebaliknya. jadi jikasomeCondition
benar,{b : 5}
akan diteruskan ke...
operator, sehingga menambah propertib
untuka
dengan nilai5
. issomeCondition
is false,false
akan diteruskan ke...
operator. sehingga tidak ada yang ditambahkan. itu pintar. Aku menyukainya.Dengan EcmaScript2015 Anda dapat menggunakan
Object.assign
:Tampilkan cuplikan kode
Beberapa komentar:
Object.assign
memodifikasi argumen pertama di tempat, tetapi juga mengembalikan objek yang diperbarui: sehingga Anda dapat menggunakan metode ini dalam ekspresi yang lebih besar yang selanjutnya memanipulasi objek.null
Anda bisa lulusundefined
atau{}
, dengan hasil yang sama. Anda bahkan bisa memberikan0
, karena nilai primitif dibungkus, danNumber
tidak memiliki properti enumerable sendiri .Bahkan lebih ringkas
Mengambil titik kedua lebih lanjut, Anda bisa mempersingkat sebagai berikut (sebagai @Jamie memiliki keluar runcing), sebagai nilai-nilai falsy tidak memiliki sifat enumerable sendiri (
false
,0
,NaN
,null
,undefined
,''
, kecualidocument.all
):Tampilkan cuplikan kode
sumber
Demo Langsung:
sumber
Menggunakan sintaks spread dengan boolean (seperti yang disarankan di sini) bukan sintaks yang valid. Spread hanya dapat digunakan dengan iterables .
Saya menyarankan yang berikut ini:
sumber
{...false}
{...false}
adalah sintaks yang valid.CopyDataProperties
dilakukan pada nilai (false
dalam hal ini). Ini melibatkan tinju primitif (bagian 7.3.23, 7.1.13). Tautan yang Anda miliki ke MDN menyebutkan "pengecualian" ini dalam tanda kurung.Bagaimana dengan menggunakan Properti Objek yang Ditingkatkan dan hanya mengatur properti jika itu benar, misalnya:
Jadi jika kondisinya tidak terpenuhi, itu tidak menciptakan properti yang disukai dan dengan demikian Anda dapat membuangnya. Lihat: http://es6-features.org/#ComputedPropertyNames
UPDATE: Bahkan lebih baik untuk mengikuti pendekatan Axel Rauschmayer dalam artikel blognya tentang menambahkan entri dalam kondisi literal dan array objek ( http://2ality.com/2017/04/conditional-literal-entries.html ):
Cukup banyak membantu saya.
sumber
false
kunci tambahan . Misalnya,{[true && 'a']: 17, [false && 'b']: 42}
adalah{a:17, false: 42}
...isConditionTrue() && { propertyName: 'propertyValue' }
lebih disederhanakan,
sumber
Jika tujuannya adalah agar objek tampak mandiri dan berada dalam satu set kawat gigi, Anda dapat mencoba ini:
sumber
Jika Anda ingin melakukan sisi server ini (tanpa jquery), Anda dapat menggunakan lodash 4.3.0:
Dan ini berfungsi menggunakan lodash 3.10.1
sumber
Saya harap ini adalah cara yang lebih efisien untuk menambahkan entri berdasarkan kondisinya. Untuk info lebih lanjut tentang cara menambahkan entri secara kondisional ke dalam objek literal.
sumber
[...condition?'':['item']]
ini akan menambahkan item string ke dalam arrayIni sudah lama dijawab, tetapi melihat ide-ide lain saya menemukan beberapa turunan yang menarik:
Tetapkan nilai yang tidak terdefinisi ke properti yang sama dan hapus setelahnya
Buat objek Anda menggunakan konstruktor anonim dan selalu tetapkan anggota yang tidak ditentukan untuk anggota boneka yang sama yang Anda hapus di bagian paling akhir. Ini akan memberi Anda satu baris (saya harap tidak terlalu rumit) per anggota + 1 baris tambahan di akhir.
sumber
Anda dapat menambahkan semua nilai yang tidak ditentukan tanpa kondisi dan kemudian gunakan
JSON.stringify
untuk menghapus semuanya:sumber
Saya akan melakukan ini
Diedit dengan satu versi kode baris
sumber
a = undefined
. Itu dapat dengan mudah diubah denganreturn { b: undefined };
: /return {};
dielse
bagiana = condition ? {b:5} : undefined;
Menggunakan perpustakaan lodash, Anda dapat menggunakan _.omitBy
Hasil ini berguna ketika Anda memiliki permintaan yang opsional
sumber
Saya pikir pendekatan pertama Anda untuk menambahkan anggota dengan syarat baik-baik saja. Aku tidak benar-benar setuju dengan tidak ingin memiliki anggota
b
daria
dengan nilaiundefined
. Ini cukup sederhana untuk menambahkanundefined
cek dengan penggunaanfor
loop denganin
operator. Tapi bagaimanapun, Anda dapat dengan mudah menulis fungsi untuk menyaringundefined
anggota.Anda juga dapat menggunakan
delete
operator untuk mengedit objek di tempatnya.sumber
Bungkus menjadi sebuah objek
Sesuatu seperti ini agak lebih bersih
Bungkus menjadi sebuah array
Atau jika Anda ingin menggunakan metode Jamie Hill dan memiliki daftar syarat yang sangat panjang maka Anda harus menulis
...
sintaks beberapa kali. Untuk membuatnya sedikit lebih bersih, Anda bisa membungkusnya menjadi sebuah array, lalu gunakanreduce()
untuk mengembalikannya sebagai objek tunggal.Atau menggunakan
map()
fungsisumber
Ini adalah solusi paling ringkas yang bisa saya buat:
sumber
Tetapkan var dengan
let
dan hanya menetapkan properti baruSekarang
msg
menjadiMenurut saya ini adalah solusi yang sangat sederhana dan mudah.
sumber
Menggunakan perpustakaan lodash, Anda bisa menggunakan _.merge
false
& conditionC adalahtrue
, makaa = { c: 5 }
true
, makaa = { b: 4, c: 5 }
false
, makaa = {}
sumber
lodash@^4.0.0
.undefined
sedang dimasukkan dalam kasus saya.