จุดใดในการใช้ ES6 Map เมื่อคีย์เป็นสตริงทั้งหมด?


35

ปุ่มวัตถุธรรมดาจะต้องเป็นสตริงในขณะที่Mapสามารถมีกุญแจประเภทใด ๆ

แต่ฉันมีประโยชน์เล็กน้อยในทางปฏิบัติ ในเกือบทุกกรณีฉันพบว่าตัวเองใช้สตริงเป็นกุญแจอยู่ดี และสันนิษฐานว่าจะช้ากว่าnew Map() {}มีเหตุผลอื่นอีกไหมทำไมจึงควรใช้Mapวัตถุธรรมดาแทนดีกว่า


3
MDNตามปกติมีการเปรียบเทียบที่ดี
Chris Hayes

1
ปีงบประมาณแผนที่ดูเหมือนจะเร็วกว่าสำหรับการตั้งค่าและการรับ
mpen

@mpen - jsperf ไม่ทำงาน คุณแน่ใจว่าmap.set('foo', 123)ทำได้เร็วกว่าobj.foo = 123หรือไม่ ถ้าเป็นเช่นนั้นน่าแปลกใจมาก
callum

@callum Uhh..no ไม่เป็นบวก คุณอาจต้องการเขียนการทดสอบประสิทธิภาพใหม่
mpen

คำตอบ:


42

มีสาเหตุบางอย่างที่ฉันชอบใช้Maps เหนือวัตถุธรรมดา ( {}) สำหรับการจัดเก็บข้อมูลรันไทม์ (แคช ฯลฯ ):

  1. .sizeคุณสมบัติให้ผมทราบว่าหลายรายการที่มีอยู่ในแผนที่นี้
  2. วิธีการสาธารณูปโภคต่างๆ - .clear(), .forEach()ฯลฯ ;
  3. พวกเขาให้ฉันทำซ้ำโดยค่าเริ่มต้น!

ทุกกรณีอื่น ๆ เช่นการส่งผ่านอาร์กิวเมนต์ของฟังก์ชันการจัดเก็บการกำหนดค่าและอื่น ๆ ล้วนเขียนด้วยวัตถุธรรมดา

นอกจากนี้โปรดจำไว้ว่า:อย่าพยายามเพิ่มประสิทธิภาพโค้ดของคุณเร็วเกินไป อย่าเสียเวลาทำเกณฑ์มาตรฐานของวัตถุธรรมดาเทียบกับแผนที่เว้นแต่ว่าโครงการของคุณกำลังมีปัญหาด้านประสิทธิภาพ


1
ฟังก์ชั่น hashcode ประจำตัวคืออะไรที่ใช้โดย Javascript
Pacerier

1
@Pacerier ===:)
gustavohenke

แผนที่เร็วกว่าวัตถุธรรมดาในสมัยนี้
jayarjo

@ gustavohenke นั่นไม่ใช่ความจริง Mapใช้อัลกอริทึม SameValueZero developer.mozilla.org/en-US/docs/Web/JavaScript/…
lolmaus - Andrey Mikhaylov

@ lolmaus-AndreyMikhaylov โอเค แต่ฉันพูดอะไรเกี่ยวกับการMapใช้สิ่งนี้หรือว่า?
gustavohenke

4

ฉันไม่แน่ใจเกี่ยวกับเรื่องนี้ แต่ฉันคิดว่าการใช้งานแผนที่ไม่ใช่เหตุผลสำหรับการใช้งาน ดูที่หน้า jsperf ที่อัปเดตนี้:

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

ดูเหมือนว่า (เมื่อจัดการกับสตริงอย่างน้อย) วัตถุนั้นเร็วกว่าแผนที่สำหรับการตั้งค่าพื้นฐานและการรับ


2
นั่นไม่ใช่วิธีที่คุณเขียนการทดสอบประสิทธิภาพ
Qix

6
นั่นไม่ใช่วิธีที่คุณเขียนความคิดเห็นที่เป็นประโยชน์ โปรดอธิบายอย่างละเอียดหากคุณมีวิธีการอื่นที่จะแนะนำ มีอะไรผิดปกติกับการทดสอบข้อเขียนเหล่านั้นอย่างไร พวกเขาในทางที่ไม่ถูกต้องหรือไม่ช่วยเหลือ?
starlogodaniel

9
ความหมายของภาษา / โครงสร้างที่กำลังทดสอบผ่าน microbenchmarks จะต้องแตกต่างกันโดยตัวแปรเดียวเท่านั้น การทดสอบของคุณแตกต่างกันไปตามจำนวนการวนซ้ำและอีกไม่กี่คนจะมีเนื้อหาลูปด้านในของพวกเขาได้รับการปรับให้เหมาะสมเนื่องจากผลลัพธ์ไม่ได้ใช้ การทดสอบตัวแปรประกาศล่วงหน้าในขณะที่คนอื่นมีการประกาศตัวแปรแบบอินไลน์กับ for loop - ซึ่งอาจทำให้เกิดความผิดปกติของประสิทธิภาพที่แตกต่างกัน
Qix

1
ใช่คุณพูดถูก ในการป้องกันของฉันรุ่นของฉันคือการปรับปรุงในหนึ่งก่อนมัน แต่ฉันพลาดทั้งประกาศล่วงหน้าและเนื้อหาวงในถูกปรับออก ผมทำงานกับเพื่อนร่วมงานที่ดีขึ้นเมื่อร่างของฉันและฉันคิดว่าการแก้ไขปัญหาเหล่านั้นjsperf.com/es6-map-vs-object-properties/88 อย่างไรก็ตามฉันคิดว่ามันถูกต้องที่จะมีรูปแบบลูปที่แตกต่างกันสำหรับโครงสร้างข้อมูลที่แตกต่างกัน ในการใช้งานจริงผู้คนจะเลือกโครงสร้างลูปที่มีประสิทธิภาพดีที่สุดและแผนที่และวัตถุมีโครงสร้างลูป "ที่เหมาะสมที่สุด" ที่แตกต่างกัน อย่างไรก็ตามขอขอบคุณสำหรับการจับ
starlogodaniel

ตกลงฉันเห็นตอนนี้ - พวกเขาเคยช้ากว่าวัตถุธรรมดา แต่ได้รับการปรับให้เหมาะสมอย่างมากในเบราว์เซอร์ที่ผ่านมา
jayarjo

0

คำตอบอื่น ๆ ไม่ได้พูดถึงหนึ่งความแตกต่างสุดท้ายระหว่างวัตถุและMaps:

Mapวัตถุถือคู่ค่าคีย์และจำเพื่อแทรกเดิมของคีย์

ดังนั้นเมื่อวนซ้ำวัตถุแผนที่จะส่งคืนคีย์ตามลำดับการแทรก

อ้างจากMDN , เน้นเหมือง


นี่คือเหตุผลหลักที่ฉันตัดสินใจใช้Mapเป็นครั้งแรกในโครงการล่าสุด ฉันมีวัตถุปกติที่ฉันต้องการแสดงใน a <table>โดยแต่ละคุณสมบัติจะอยู่ในแถวที่ระบุ

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

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

ฉันเขียนฟังก์ชันเพื่อแปลงวัตถุให้เป็นMapไปตามคำสั่งของคีย์ที่ต้องการ:

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

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

    return map;
}

จากนั้นแผนที่จะวนซ้ำตามลำดับที่ต้องการ:

let productMap = objectToMap( product, productPropertyOrder );

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

แน่นอนว่านี่เป็นบิตที่ถูกประดิษฐ์ขึ้นเพราะเราสามารถแสดงได้ดีเมื่อวนคำสั่งคุณสมบัติโดยไม่ต้องสร้าง a Mapในกระบวนการ:

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

แต่ถ้าคุณมีอาร์เรย์ของวัตถุดังกล่าวและกำลังจะแสดงให้พวกเขาหลายแห่งแล้วแปลงพวกเขาทั้งหมดเป็นแผนที่ก่อนทำให้รู้สึก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.