ECMAScript 5 memiliki filter()
prototipe untuk Array
tipe, tetapi bukan Object
tipe, jika saya mengerti dengan benar.
Bagaimana cara saya menerapkan s filter()
untuk Object
dalam JavaScript?
Katakanlah saya punya objek ini:
var foo = {
bar: "Yes"
};
Dan saya ingin menulis filter()
yang berfungsi di Object
s:
Object.prototype.filter = function(predicate) {
var result = {};
for (key in this) {
if (this.hasOwnProperty(key) && !predicate(this[key])) {
result[key] = this[key];
}
}
return result;
};
Ini berfungsi ketika saya menggunakannya dalam demo berikut, tetapi ketika saya menambahkannya ke situs saya yang menggunakan jQuery 1.5 dan jQuery UI 1.8.9, saya mendapatkan kesalahan JavaScript di FireBug.
javascript
jquery
object
filtering
AgileMeansDoAsLittleAsPossible
sumber
sumber
Object.prototype
: bugs.jquery.com/ticket/2721Jawaban:
Tidak pernah berkembang
Object.prototype
.Hal-hal buruk akan terjadi pada kode Anda. Segalanya akan pecah. Anda memperluas semua jenis objek, termasuk objek literal.
Inilah contoh cepat yang dapat Anda coba:
Alih-alih membuat fungsi yang Anda melewati objek.
sumber
Object.prototype
, tetapi hanya untuk menempatkan fungsiObject
. Kedua, ini adalah kode OP . Jelas niat OP adalah untuk memiliki.filter()
sedemikian rupa sehingga menyaring hasil positif. Dengan kata lain, ini adalah filter negatif, di mana nilai pengembalian positif berarti dikeluarkan dari hasilnya. Jika Anda melihat contoh jsFiddle, ia memfilter properti yang adaundefined
.Object.prototype
. Dari pertanyaan: "Ini berfungsi ..., tetapi ketika saya menambahkannya ke situs saya ..., saya mendapatkan kesalahan JavaScript" Jika OP memutuskan untuk menerapkan.filter()
dengan perilaku yang berlawanan dari ituArray.prototpe.filter
, itu terserah padanya. Silakan tinggalkan komentar di bawah pertanyaan jika Anda ingin memberi tahu OP bahwa kode itu salah, tetapi jangan katakan bahwa saya salah melakukannya ketika itu bukan kode saya.Pertama-tama, itu dianggap praktik buruk untuk diperluas
Object.prototype
. Sebaliknya, menyediakan fitur Anda sebagai fungsi utilitas padaObject
, seperti ada sudah beradaObject.keys
,Object.assign
,Object.is
, ... dll.Saya berikan di sini beberapa solusi:
reduce
danObject.keys
Object.assign
map
dan menyebar sintaks alih-alihreduce
Object.entries
danObject.fromEntries
1. Menggunakan
reduce
danObject.keys
Dengan
reduce
danObject.keys
untuk menerapkan filter yang diinginkan (menggunakan sintaks panah ES6 ):Perhatikan bahwa dalam kode di atas
predicate
harus merupakan kondisi inklusi (bertentangan dengan kondisi pengecualian OP yang digunakan), sehingga sesuai dengan caraArray.prototype.filter
kerjanya.2. As (1), dalam kombinasi dengan
Object.assign
Dalam solusi di atas operator koma digunakan di
reduce
bagian untuk mengembalikanres
objek yang bermutasi . Tentu saja ini dapat ditulis sebagai dua pernyataan, bukan satu ungkapan, tetapi yang terakhir lebih ringkas. Untuk melakukannya tanpa operator koma, Anda bisa menggunakanObject.assign
sebagai gantinya, yang tidak mengembalikan objek bermutasi:3. Menggunakan
map
dan menyebarkan sintaks sebagai gantireduce
Di sini kita memindahkan
Object.assign
panggilan keluar dari loop, sehingga hanya dibuat sekali, dan memberikannya kunci individual sebagai argumen terpisah (menggunakan sintaksis penyebaran ):4. Menggunakan
Object.entries
danObject.fromEntries
Ketika solusi menerjemahkan objek ke array perantara dan kemudian mengubahnya kembali menjadi objek biasa, akan berguna untuk menggunakan
Object.entries
(ES2017) dan sebaliknya (yaitu membuat objek dari array pasangan kunci / nilai ) denganObject.fromEntries
( ES2019).Ini mengarah ke metode "satu garis" pada
Object
:Fungsi predikat mendapat pasangan kunci / nilai sebagai argumen di sini, yang sedikit berbeda, tetapi memungkinkan lebih banyak kemungkinan dalam logika fungsi predikat.
sumber
x => x.Expression.Filters.Filter
.Filter
ada di akhirnya, tetapi jika itu adalah sebuah fungsi, Anda perlu menyebutnya (x => x.Expression.Filters.Filter()
)Jika Anda ingin menggunakan garis bawah atau tanda lahir , Anda dapat menggunakan
pick
(atau kebalikannya,omit
).Contoh dari dokumen garis bawah:
Atau dengan callback (untuk menginap , gunakan pickBy ):
sumber
Pendekatan ES6 ...
Bayangkan Anda memiliki objek di bawah ini:
Buat fungsi:
Dan menyebutnya:
dan akan kembali :
sumber
!predicate
kode mereka sendiri).Seperti yang sudah dinyatakan patrick, ini adalah ide yang buruk, karena hampir pasti akan memecahkan kode pihak ketiga yang ingin Anda gunakan.
Semua perpustakaan seperti jquery atau prototipe akan rusak jika Anda memperluas
Object.prototype
, alasannya adalah bahwa iterasi malas atas objek (tanpahasOwnProperty
pemeriksaan) akan rusak karena fungsi yang Anda tambahkan akan menjadi bagian dari iterasi.sumber
Bagaimana tentang:
Atau...
sumber
Diberikan
kemudian :
Tampilkan cuplikan kode
sumber
Saya telah membuat
Object.filter()
yang tidak hanya memfilter menurut fungsi, tetapi juga menerima larik kunci untuk disertakan. Parameter ketiga opsional akan memungkinkan Anda untuk membalikkan filter.Diberikan:
Himpunan:
Fungsi:
Kode
Penafian : Saya memilih untuk menggunakan inti Ext JS untuk singkatnya. Tidak merasa perlu untuk menulis checker tipe untuk tipe objek karena itu bukan bagian dari pertanyaan.
sumber
Solusi saya:
Kasus uji:
https://gist.github.com/bernardoadc/872d5a174108823159d845cc5baba337
sumber
Solusi di Vanilla JS dari tahun 2020.
Anda dapat memfilter
romNumbers
objek dengan kunci:Atau memfilter
romNumbers
objek berdasarkan nilai:sumber
Jika Anda ingin bermutasi objek yang sama daripada membuat yang baru.
Contoh berikut akan menghapus semua nilai 0 atau kosong:
sumber
Seperti semua orang katakan, jangan main-main dengan prototipe. Sebagai gantinya, cukup tulis fungsi untuk melakukannya. Ini versi saya dengan
lodash
:sumber
Saya menggunakan ini ketika saya membutuhkannya:
sumber
Dalam kasus ini saya menggunakan jquery $ .map, yang dapat menangani objek. Seperti disebutkan pada jawaban lain, bukan praktik yang baik untuk mengubah prototipe asli ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Bad_practice_Extension_of_native_prototypes )
Di bawah ini adalah contoh pemfilteran hanya dengan memeriksa beberapa properti objek Anda. Ini mengembalikan objek sendiri jika kondisi Anda benar atau mengembalikan
undefined
jika tidak. Theundefined
properti akan membuat rekor menghilang dari daftar objek Anda;sumber
$.map
dapat mengambil objek, tetapi mengembalikan array, sehingga nama properti asli hilang. OP membutuhkan objek polos yang difilter.