Adakah poin dalam menggunakan Peta ES6 saat semua kuncinya adalah string?

36

Kunci objek polos harus berupa string, sedangkan a Mapdapat memiliki kunci jenis apa pun.

Tetapi saya tidak banyak menggunakan ini dalam praktik. Di hampir semua kasus, saya tetap menggunakan string sebagai kunci. Dan mungkin new Map()lebih lambat dari {}. Jadi, apakah ada alasan lain mengapa mungkin lebih baik menggunakan Mapobjek biasa?

callum
sumber
3
MDN , seperti biasa, memiliki perbandingan yang bagus.
Chris Hayes
1
FYI, Peta tampaknya lebih cepat untuk pengaturan dan pengambilan.
buka
@mpen - jsperf sedang down sekarang. Apakah Anda yakin map.set('foo', 123)melakukan lebih cepat daripada obj.foo = 123? Jika demikian, itu sangat mengejutkan
callum
@callum Uhh..tidak, tidak positif. Anda mungkin ingin menulis beberapa tes kinerja baru.
mpen

Jawaban:

42

Ada beberapa alasan mengapa saya lebih suka menggunakan objek Maps over plain ( {}) untuk menyimpan data runtime (cache, dll):

  1. The .sizeproperti membuat saya tahu berapa banyak entri ada dalam Peta ini;
  2. Berbagai metode utilitas - .clear(), .forEach(), dll;
  3. Mereka memberi saya iterator secara default!

Setiap kasus lain, seperti melewati argumen fungsi, menyimpan konfigurasi dan lain-lain, semuanya ditulis menggunakan objek polos.

Juga, ingat: Jangan mencoba mengoptimalkan kode Anda terlalu dini. Jangan buang waktu Anda melakukan tolok ukur objek biasa vs Peta kecuali proyek Anda mengalami masalah kinerja.

gustavohenke
sumber
1
Apa fungsi kode hash identitas yang digunakan oleh Javascript?
Pacerier
1
@Pacerier ===:)
gustavohenke
Peta jauh lebih cepat daripada objek biasa hari ini.
jayarjo
@gustavohenke Itu tidak benar. Mapmenggunakan algoritma SameValueZero. developer.mozilla.org/en-US/docs/Web/JavaScript/…
lolmaus - Andrey Mikhaylov
@ lolmaus-AndreyMikhaylov oke, tapi apakah saya mengatakan sesuatu tentang Mapmenggunakan ini atau itu?
gustavohenke
4

Saya tidak yakin tentang ini, tapi saya pikir kinerja BUKAN alasan untuk menggunakan Maps. Lihatlah halaman jsperf yang diperbarui ini:

http://jsperf.com/es6-map-vs-object-properties/73

Sepertinya (ketika berhadapan dengan string paling tidak) objek jauh lebih cepat daripada peta untuk pengaturan dasar dan mendapatkan.

starlogodaniel
sumber
2
Bukan itu cara Anda menulis tes kinerja.
Qix
6
Bukan itu cara Anda menulis komentar yang bermanfaat. Jangan ragu untuk menguraikan jika Anda memiliki metodologi alternatif untuk disarankan. Apa, khususnya, yang salah dengan bagaimana tes-tes itu ditulis? Apakah mereka dengan cara apa pun tidak valid atau tidak membantu?
starlogodaniel
9
Semantik bahasa / konstruksi yang diuji melalui microbenchmark hanya boleh berbeda satu variabel. Tes Anda bervariasi berdasarkan jumlah iterasi, dan beberapa di antaranya akan dioptimalkan konten loop dalamnya karena hasilnya tidak digunakan. Beberapa tes pra-deklarasikan variabel sementara yang lain memiliki deklarasi variabel sesuai dengan for loop - yang mungkin menimbulkan ketidaknormalan kinerja yang berbeda.
Qix
1
Aduh, kamu benar sekali. Dalam pembelaan saya, versi saya adalah perbaikan dari yang sebelumnya, tetapi saya melewatkan pra-deklarasi dan isi loop dalam dioptimalkan. Saya bekerja dengan seorang kolega yang memperbaiki konsep saya dan saya pikir menyelesaikan masalah-masalah itu: jsperf.com/es6-map-vs-object-properties/88 . Namun, saya pikir itu sah untuk memiliki gaya loop yang berbeda untuk struktur data yang berbeda; dalam penggunaan nyata, orang akan memilih struktur loop dengan kinerja terbaik, dan Map dan Object memiliki struktur loop "optimal" yang berbeda. Bagaimanapun, terima kasih atas tangkapannya.
starlogodaniel
Ok saya mengerti sekarang - mereka dulu lebih lambat dari objek biasa, tetapi telah sangat dioptimalkan di browser terbaru.
jayarjo
0

Jawaban lain tidak menyebutkan satu perbedaan terakhir antara objek dan Maps:

The Mapobjek memegang pasangan kunci-nilai dan mengingat urutan penyisipan asli dari kunci .

Jadi, ketika iterasi di atasnya, objek Peta mengembalikan kunci dalam urutan penyisipan.

Kutipan dari MDN , beri penekanan pada saya


Ini adalah alasan utama saya memutuskan untuk menggunakan Mapuntuk pertama kalinya dalam proyek baru-baru ini. Saya memiliki objek normal yang perlu saya tampilkan di <table>, dengan setiap properti berada di baris tertentu.

let productPropertyOrder = [ "name", "weight", "price", "stocked" ];

let product =
{
    name: "Lasagne",
    weight: "1kg",
    price: 10,
    stocked: true
}

Saya menulis fungsi untuk mengubah objek menjadi Mapsesuai dengan urutan kunci yang diinginkan:

function objectToMap( obj, order )
{
    let map = new Map();

    for ( const key of order )
    {
        if ( obj.hasOwnProperty( key ) )
        {
            map.set( key, obj[ key ] );
        }
    }

    return map;
}

Maka peta bisa diulangi dalam urutan yang diinginkan:

let productMap = objectToMap( product, productPropertyOrder );

for ( const value of productMap.values() )
{
    let cell = document.createElement( "td" );
    cell.innerText = value;
    row.appendChild( cell );
}

Tentu saja ini sedikit dibuat-buat karena orang bisa juga menampilkan ketika iterating atas urutan properti tanpa membuat Mapdalam proses:

for ( const key of productPropertyOrder )
{
    if ( product.hasOwnProperty( key ) )
    {
        let value = product[ key ];
        // create cell
    }
}

Tetapi jika Anda memiliki larik objek seperti itu dan akan menampilkannya di banyak tempat, lalu mengonversinya semua menjadi peta terlebih dahulu masuk akal.

WD40
sumber