Bagaimana fungsi tingkat tinggi, seperti .map (), bekerja secara internal di JavaScript?

17

Semua orang saat ini mencoba menggunakan fungsi tingkat tinggi semacam ini untuk mendapatkan hasil yang menjanjikan dengan menulis lebih sedikit kode. Tetapi saya bertanya-tanya bagaimana fungsi-fungsi ini bekerja secara internal.

Misalkan jika saya menulis sesuatu seperti

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

Saya tahu bahwa setiap elemen dari array 'angka' adalah iterasi satu per satu, tetapi bagaimana caranya ?

Saya mencoba mencarinya, tetapi saya belum mendapatkan jawaban yang memuaskan.

Bilal Khan
sumber
10
Lihatlah polyfil dari Array.map
AZ_
Ini adalah fungsi yang disebut mapyang ditambahkan ke tipe Array. Fungsi ini mengambil fungsi sebagai parameter yang kemudian dipanggil saat perulangan melalui array. Nilai balik dari panggilan fungsi kemudian dikembalikan dalam array.
ssc-hrep3
peta pada dasarnya bekerja seperti foreach untuk iterating array artinya akan mendapatkan semua elemen array satu per satu dan kemudian menerapkan perintah / operasi yang diberikan pada setiap elemen dan kemudian mendorongnya ke array baru.
Adnan Tariq

Jawaban:

23

.maphanyalah metode yang menerima panggilan balik, memanggil panggilan balik untuk setiap item array, dan memberikan nilai ke array baru. Tidak ada yang istimewa tentang itu. Anda bahkan dapat menerapkannya sendiri dengan mudah:

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]

Untuk sepenuhnya memenuhi spesifikasi, Anda juga perlu memeriksa, antara lain, bahwa itu thisadalah objek, bahwa itu callbackbisa dipanggil, dan ke .callcallback dengan parameter kedua diteruskan ke myMapjika ada satu, tetapi itu adalah rincian tidak penting untuk pemahaman awal tentang fungsi tingkat tinggi.

Performa Tertentu
sumber
8
Ini mengingatkan saya pada beberapa jawaban lain ...
Bergi
7

Saya kira setiap vendor seharusnya mengimplementasikannya sesuai spesifikasi

Implementasi aktual, misalnya V8 bisa sedikit rumit, lihat jawaban ini sebagai permulaan. Anda juga dapat merujuk sumber v8 di github tetapi mungkin tidak mudah untuk memahami hanya satu bagian dalam isolasi.

Dikutip dari jawaban di atas:

Pengembang V8 di sini. Kami memiliki beberapa teknik implementasi yang berbeda untuk "builtin": beberapa ditulis dalam C ++, beberapa di Torque, beberapa dalam apa yang kami sebut CodeStubAssembler, dan beberapa langsung dalam perakitan. Dalam versi V8 sebelumnya, beberapa diimplementasikan dalam JavaScript. Masing-masing strategi ini memiliki kekuatan sendiri (menukar kompleksitas kode, kemampuan debuggabilitas, kinerja dalam berbagai situasi, ukuran biner, dan konsumsi memori); ditambah selalu ada alasan historis bahwa kode telah berkembang dari waktu ke waktu.

ES2015 spec:

  1. Biarkan O menjadi ToObject ( nilai ini ).
  2. ReturnIfAbrupt ( O ).
  3. Biarkan len menjadi ToLength (Get ( O , "length")).
  4. ReturnIfAbrupt ( len ).
  5. Jika IsCallable ( callbackfn ) salah , lempar pengecualian TypeError .
  6. Jika thisArg diberikan, misalkan T adalah thisArg ; kalau tidak biarkan T tidak terdefinisi .
  7. Biarkan A menjadi ArraySpeciesCreate ( O , len ).
  8. ReturnIfAbrupt ( A ).
  9. Biarkan k menjadi 0.
  10. Ulangi, sementara k < len
    1. Biarkan Pk menjadi ToString ( k ).
    2. Biarkan kPresent menjadi HasProperty ( O , Pk ).
    3. ReturnIfAbrupt ( kPresent ).
    4. Jika kPresent adalah benar , maka
      1. Biarkan kValue menjadi Get ( O , Pk ).
      2. ReturnIfAbrupt ( kValue ).
      3. Biarkan mappedValue menjadi Panggilan ( callbackfn , T , « kValue , k , O »).
      4. ReturnIfAbrupt ( mappedValue ).
      5. Biarkan status menjadi CreateDataPropertyOrThrow ( A , Pk , mappedValue ).
      6. ReturnIfAbrupt ( status ).
    5. Tambah k sebanyak 1.
  11. Kembali A .
sabithpocker
sumber
2
Saya ingin tahu, spesifikasi <li> list-style-typeini tidak dapat disalin di Chrome atau FF. Apakah Anda menulis angka secara manual, atau apakah ada metode yang lebih baik yang saya lewatkan?
Kinerja Tertentu
5
@CertainPerformance lol. Salin HTML dari sumber, HTML ke alat markdown online.
sabithpocker