ฟังก์ชันลำดับสูงกว่าเช่น. map () ทำงานภายใน JavaScript ได้อย่างไร


17

ทุกวันนี้ทุกคนพยายามที่จะใช้ฟังก์ชั่นลำดับสูงเหล่านี้เพื่อให้ได้ผลลัพธ์ที่มีแนวโน้มโดยการเขียนโค้ดน้อย แต่ฉันสงสัยว่าฟังก์ชั่นเหล่านี้ทำงานอย่างไรภายใน

สมมติว่าถ้าฉันเขียนบางอย่างเช่น

var numbers = [16, 25, 36];
var results = numbers.map(Math.sqrt);
console.log(results); // [4, 5, 6]

ฉันรู้ว่าองค์ประกอบของ 'จำนวน' อาร์เรย์แต่ละวนหนึ่งโดยหนึ่ง แต่วิธี ?

ฉันพยายามค้นหา แต่ฉันยังไม่ได้รับคำตอบที่น่าพอใจ


10
ดู polyfil ของArray.map
AZ_

มันเป็นฟังก์ชั่นที่เรียกว่าmapซึ่งเพิ่มเข้าไปในประเภทอาเรย์ ฟังก์ชั่นนี้ใช้ฟังก์ชั่นเป็นพารามิเตอร์ซึ่งเรียกว่าในขณะที่วนลูปผ่านอาร์เรย์ ค่าส่งคืนของการเรียกใช้ฟังก์ชันจะถูกส่งคืนในอาร์เรย์
ssc-hrep3

แผนที่โดยทั่วไปจะทำงานเหมือน foreach สำหรับการวนซ้ำหมายความว่ามันจะได้รับองค์ประกอบทั้งหมดของอาร์เรย์หนึ่งโดยหนึ่งแล้วใช้คำสั่งที่กำหนด / การดำเนินการกับแต่ละองค์ประกอบแล้วผลักมันเข้าไปในอาร์เรย์ใหม่
Adnan Tariq

คำตอบ:


23

.mapเป็นเพียงวิธีการที่ยอมรับการเรียกกลับเรียกใช้การเรียกกลับสำหรับทุกรายการของอาร์เรย์และกำหนดค่าให้กับอาร์เรย์ใหม่ ไม่มีอะไรพิเศษเกี่ยวกับมัน คุณสามารถใช้งานได้ด้วยตัวเองอย่างง่ายดาย:

Array.prototype.myMap = function(callback) {
  const newArr = [];
  for (let i = 0; i < this.length; i++) {
    newArr.push(callback(this[i], i, this));
  }
  return newArr;
}

var numbers = [16, 25, 36];
var results = numbers.myMap(Math.sqrt);
console.log(results); // [4, 5, 6]

เพื่อให้เป็นไปตามข้อกำหนดอย่างสมบูรณ์คุณยังต้องตรวจสอบสิ่งอื่น ๆ ว่าthisเป็นวัตถุที่callbackสามารถ.callโทรได้และการติดต่อกลับที่มีพารามิเตอร์ตัวที่สองส่งผ่านไปmyMapหากมี แต่ไม่มีรายละเอียด มีความสำคัญต่อความเข้าใจเริ่มต้นของฟังก์ชันลำดับสูงกว่า


8
นี่ทำให้ฉันนึกถึงคำตอบอื่น ๆ ...

7

ฉันเดาผู้ขายทุกคนควรจะใช้มันตามสเป็ค

การใช้งานจริงเช่น V8 อาจซับซ้อนเล็กน้อยดูคำตอบนี้เพื่อเริ่มต้น นอกจากนี้คุณยังสามารถอ้างถึงแหล่งที่มาของ v8 ใน GitHub แต่มันอาจไม่ง่ายที่จะเข้าใจเพียงส่วนเดียวในการแยก

อ้างจากคำตอบข้างต้น:

นักพัฒนา V8 ที่นี่ เรามีเทคนิคการใช้งานที่แตกต่างกันสำหรับ "builtins": บางส่วนเขียนใน C ++, บางส่วนใน Torque, บางอย่างในสิ่งที่เราเรียกว่า CodeStubAssembler ใน V8 เวอร์ชันก่อนหน้ามีการใช้งานบางอย่างใน JavaScript แต่ละกลยุทธ์เหล่านี้มีจุดแข็งของตัวเอง (ซื้อขายความซับซ้อนของรหัสการดีบักประสิทธิภาพในสถานการณ์ต่าง ๆ ขนาดไบนารีและการใช้หน่วยความจำ) นอกจากนี้ยังมีเหตุผลทางประวัติศาสตร์ที่รหัสมีการพัฒนาอยู่ตลอดเวลา

ข้อมูลจำเพาะ ES2015:

  1. ให้Oเป็น ToObject ( ค่านี้ )
  2. ReturnIfAbrupt ( O )
  3. ให้lenเป็น ToLength (Get ( O , "length"))
  4. ReturnIfAbrupt ( len )
  5. ถ้า IsCallable ( callbackfn ) เป็นเท็จให้โยนข้อยกเว้นTypeError
  6. หากthisArgถูกจัดให้Tเป็นthisArg ; อื่นให้ทีจะไม่ได้กำหนด
  7. ให้A be ArraySpeciesCreate ( O , len )
  8. ReturnIfAbrupt ( A )
  9. ให้kเป็น 0
  10. ทำซ้ำขณะที่k < len
    1. ให้Pkเป็น ToString ( k )
    2. ให้kPresentเป็น HasProperty ( O , Pk )
    3. ReturnIfAbrupt ( kPresent )
    4. ถ้าkPresentเป็นจริงดังนั้น
      1. ให้kValueเป็น Get ( O , Pk )
      2. ReturnIfAbrupt ( kValue )
      3. ให้mappedValueเป็นการโทร ( callbackfn , T , « kValue , k , O »)
      4. ReturnIfAbrupt ( แมปค่า )
      5. ให้สถานะเป็น CreateDataPropertyOrThrow ( A , Pk , mappedValue )
      6. ReturnIfAbrupt ( สถานะ )
    5. เพิ่มk 1
  11. ย้อนกลับ

2
ฉันสงสัยว่าข้อมูลจำเพาะ<li> list-style-typeไม่สามารถคัดลอกได้ใน Chrome หรือ FF คุณเขียนตัวเลขด้วยตนเองหรือมีวิธีที่ดีกว่าที่ฉันหายไป?
CertainPerformance

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