. map () กำลังทำอะไรในสถานการณ์นี้


95

เมื่อใช้ Chrome Console นี่คืออินพุตและเอาต์พุตของฉัน:

[0].map(Array);

[[0, 0, [0]]]; // output

เกิดอะไรขึ้นที่นี่?

แก้ไข

เหตุผลนี้ทำให้ฉันอยากรู้อยากเห็นเพราะบางอย่างเช่น

[0].map(String);

จะกลับมา

["0"];

และไม่

["0", "0", "String"]

34
ฉันคิดว่าเพราะเขาต้องการ Javascript WTF เพื่อที่จะรู้สึกมีความสุข
npst

12
โอ้มันเป็นเพียงตัวแปร wtf-y น้อยกว่า['10', '10', '10'].map(parseInt)
gronostaj

2
.map()พฤติกรรมแปลก ๆ อีกอย่าง: stackoverflow.com/questions/14528397/…โดยทั่วไปคุณต้องระมัดระวังเมื่อใช้.map()กับฟังก์ชันที่ใช้อาร์กิวเมนต์มากกว่าหนึ่งรายการ
Barmar

2
Just do[0].map(console.log)
Bergi

1
@Jacksonkr: ขอบคุณสำหรับคำตอบ ฉันคิดว่ามันเป็นแบบนี้ฉันเขียนความคิดเห็นอธิบายว่าการได้เห็น JS WTF ทำให้ฉันมีความสุขฉันไม่ต้องใช้ภาษาบ่อยๆ มีคนถามว่าทำไมฉันจะดูคำถาม JS ถ้าฉันไม่ชอบภาษา npst ตอบและสองความคิดเห็นแรกถูกลบ เป็นเรื่องตลกที่ความคิดเห็นของเขายังคงได้รับการโหวตใช่
Eric Duminil

คำตอบ:


123

.map()ฟังก์ชั่นคือการเรียกArray()ฟังก์ชั่นที่มีสามข้อโต้แย้งค่าขององค์ประกอบอาร์เรย์ซึ่งเป็น0ดัชนีขององค์ประกอบที่ยัง0และการอ้างอิงไปยังอาร์เรย์ทั้งหมด

ดังนั้นจึงเป็นเช่นนี้:

var a = [0];
var index = 0
Array(a[index], index, a);   // create array with three elements

อาร์เรย์ที่ส่งคืนมาArray()จะกลายเป็นองค์ประกอบแรกของอาร์เรย์ที่.map()สร้างขึ้นดังนั้นระดับพิเศษของการซ้อนใน[[0, 0, [0]]]ผลลัพธ์ของคุณ

แก้ไขเกี่ยวกับการแก้ไขของคุณ: เมื่อคุณบอก[0].map(String);ว่าผลลัพธ์String()ถูกเรียกด้วยอาร์กิวเมนต์สามตัวที่เหมือนString(a[index], index, a)กัน แต่String()ฟังก์ชันจะละเว้นทั้งหมดยกเว้นอาร์กิวเมนต์แรกในขณะที่Array()ใช้อาร์กิวเมนต์ที่ให้มาทั้งหมด


39

ประการแรก , Arrayสามารถใช้เป็นฟังก์ชั่นในการสร้างอาร์เรย์:

var arr = Array(1, 2, "Hello");

console.log(arr); // [1, 2, "Hello"]

ประการที่สอง , mapผ่านสามพารามิเตอร์ที่จะโทรกลับของ: องค์ประกอบดัชนีจาก array และอาเรย์ของตัวเอง

ดังนั้นเนื่องจากอาร์เรย์ของคุณมีองค์ประกอบเดียวบรรทัด:

[0].map(Array);

เทียบเท่ากับ:

[Array(0, 0, [0])];     // the element 0 in the original array will be mapped into Array(0, 0, [0])

6

หลังจากที่คุณอัปเดตคำถาม คำตอบอื่น ๆ จะให้ข้อมูลเกี่ยวกับแผนที่แก่คุณ

เพื่อตอบว่าเหตุใดอาร์เรย์และสตริงจึงมีลักษณะแตกต่างจากตัวสร้าง

ตัวสร้างสตริงยอมรับ 1 พารามิเตอร์String (สิ่ง)ในขณะที่อาร์เรย์อาร์เรย์ใหม่ (element0, element1 [, ... [, elementN]])


2
เป็นเหตุผลเดียวกับที่.map(Number)แปลงทุกรายการเป็นตัวเลขแทนที่จะส่งคืนสิ่งที่ต้องการ[3, 2, [4, 1, 3]]สำหรับทุกรายการ
user4642212

@Xufox ใช่คำตอบอยู่ในตัวสร้าง :)
Volodymyr Bilyachat

4

โทร

[0].map(Array);

ให้ผลลัพธ์เหมือนกับว่าคุณเขียนอะไรแบบนี้:

[0].map(function (value, index, array) {
    return Array(value, index, array);
})

ฟังก์ชันแผนที่เรียกใช้ฟังก์ชันArrayโดยมีพารามิเตอร์สามตัว ได้แก่ ค่าขององค์ประกอบดัชนีขององค์ประกอบและอาร์เรย์ทั้งหมด การเรียกนี้จะArrayส่งคืนอาร์เรย์ของคุณด้วย 3 องค์ประกอบ ได้แก่ ค่า (ตัวเลข0) ดัชนี (ตัวเลข0) อาร์เรย์ทั้งหมด ( [0])

และอาร์เรย์ใหม่นี้ถูกรวมไว้ใน Array เดิมเนื่องจากคุณได้แมปองค์ประกอบดั้งเดิม (ตัวเลข0) กับองค์ประกอบใหม่ (อาร์เรย์ 3 องค์ประกอบ)

หมายเหตุ: คุณอาจคุ้นเคยกับการใช้เฉพาะพารามิเตอร์แรกเช่น in

array.map(function (a) { return a * a; });

หรือใช้แค่สองเพื่อรับดัชนี

array.map(function (item, index) { return "index=" + index + ", value=" + item; });

แต่คุณต้องจำไว้ว่าmapยังมีพารามิเตอร์ 3 ตัวที่คุณไม่สนใจในฟังก์ชันเรียกกลับของคุณ นั่นเป็นเหตุผลว่าทำไมรหัสเช่น:

[0].map(String);

ผลตอบแทน

["0"]

เป็นเพราะฟังก์ชันStringดูแลเฉพาะพารามิเตอร์แรกและละเว้นพารามิเตอร์ที่ส่งผ่านอื่น ๆ ถ้าคุณโทร

String(11, "Some", "other", "ignored", "parameters")

คุณจะยังคงได้รับ

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