Mengapa kerangka / pustaka JavaScript memiliki fungsi yang sudah ada dalam JavaScript murni?

61

Saya bertanya-tanya mengapa kerangka kerja / perpustakaan memiliki pembantu mereka sendiri meskipun sudah ada secara native.

Mari kita ambil jQuery dan AngularJS . Mereka memiliki eachfungsi iterator sendiri :

Tapi kami punya Array.prototype.forEach.

Demikian pula,

Tetapi kami memiliki JSON.parse()fungsi dalam JavaScript vanilla.

Cihad Turhan
sumber
75
Sebagai seseorang yang mengingat masa lalu yang buruk dalam pengembangan web, pertanyaan ini membuat saya menangis.
josh3736
3
@ josh3736 Setidaknya Anda masih tidak harus mendukung IE6 ('tho, untungnya hanya dalam cara "membuatnya bekerja, itu bisa terlihat seperti omong kosong")
Izkata
12
jQuery.eachdan Array.prototype.forEachtidak setara.
zzzzBov
3
Yang harus Anda tanyakan pada diri sendiri adalah: berapa banyak fungsi yang ditemukan di vanillaJS sekarang, berasal dari toolkit seperti jQ dan sejenisnya? Jawabannya adalah: banyak . Ini menimbulkan pertanyaan: mengapa kita masih menggunakannya? Mengapa menyertakan jQuery $.each, dan tidak menggunakan yang asli (dan lebih cepat) Array.prototype.forEach?
Elias Van Ootegem
1
@ josh3736 Tidak apa-apa ... i.stack.imgur.com/HJs4V.jpg
Crono

Jawaban:

94

Karena ketika perpustakaan itu ditulis, beberapa browser utama tidak mendukung fitur-fitur itu. Setelah ditulis dan digunakan, fitur-fitur ini tidak dapat dihapus dari perpustakaan ini tanpa merusak banyak aplikasi.

(Dalam hal ini, "peramban utama" berarti peramban yang masih memiliki pangsa pasar yang besar, yang mencakup peramban versi lama seperti Internet Explorer, di mana sejumlah besar pengguna tidak perlu memutakhirkan ke versi terbaru.)

Gort the Robot
sumber
44
$ ('marquee'). masing-masing (function () {$ (this) .append ($ ('<bgsound />', {src: "good-answer.mp3"}));});
Pierre Arlaud
37
@ dirkk Bukan berarti browser terbaru tidak mendukungnya. Tidak semua orang cukup beruntung memiliki pemirsa yang menggunakan browser terbaru.
George Reith
14
Array.prototype.forEachiterates hanya melalui array - kedua fungsi perpustakaan iterator dapat beralih di atas array atau objek.
JoeG
3
Fungsinya ada untuk mendukung browser lama dan untuk mendukung kode lama yang memanggil perpustakaan dan programmer tidak ingin menulis ulang. Bahkan jika Anda telah kehilangan dukungan untuk IE 6 Anda mungkin masih memiliki beberapa JavaScript yang digunakan tertulis ketika Anda memang perlu mendukung salinan kuno IE.
Michael Shopsin
6
Banyak fungsi ini (mis. JQuery.parseJSON ()) cukup periksa apakah browser mendukungnya dan kemudian mengatur dirinya sendiri ke metode browser, dan hanya menggunakan alternatif pada browser yang tidak kompatibel!
Josef
35

Karena browser yang berbeda memiliki implementasi dan fitur yang berbeda dalam mesin JavaScript mereka. Kode "vanilla-JS" yang sama dapat berjalan secara berbeda pada dua browser yang berbeda, atau bahkan dua versi berbeda dari browser yang sama.

Lapisan abstraksi yang disediakan oleh perpustakaan JS populer adalah cara mengatasi ini. Di balik layar, ia bekerja di sekitar berbagai kapasitas dan batasan browser dan menawarkan API terpadu yang mudah digunakan. Ini, pada gilirannya, memungkinkan operasi umum seperti mendapatkan objek DOM atau mengambil data JSON menjadi konsisten, efisien dan agnostik browser.

Ini membuat hidup jauh lebih mudah bagi pengembang yang sekarang dapat fokus pada kode apa yang harus dilakukan, daripada bagaimana seharusnya ditulis untuk bekerja dengan browser X atau Y.

Crono
sumber
2
Perilaku "core JS" ditentukan dengan baik dan diuji di semua browser.
Domenic
2
Selain Syntax @Domenic, implementasi javascript memang berbeda dari browser ke browser. Ada properti, metode, acara, dan fitur yang akan Anda temukan hanya dalam beberapa browser saja, atau bahkan hanya dalam satu browser saja.
Crono
1
Ya, browser memiliki fitur yang tidak standar. Itu tidak ada hubungannya dengan fitur standar yang dibahas dalam pertanyaan ini.
Domenic
8
@Domenik Jika dengan "fitur standar yang dibahas dalam pertanyaan" yang Anda maksud Array.prototype.forEachdan JSON.parsefungsinya, pencarian cepat di Google akan menunjukkan bahwa Anda salah. JSONobjek tidak didukung pada IE7 dan forEachtidak didefinisikan pada beberapa versi Opera. Namun perpustakaan seperti jQuery tahu tentang keterbatasan ini dan bekerja di sekitar mereka di belakang layar. Jadi saya pikir jawaban saya benar.
Crono
28

1. Kompatibilitas mundur

JavaScript adalah implementasi dari ECMAScript . Sebagian besar fungsi tersebut diperkenalkan dalam ECMAScript 5 (ES5) namun banyak browser lama yang masih memiliki pangsa pasar yang cukup signifikan tidak mendukung fungsi-fungsi ini (lihat tabel kompatibilitas ECMAScript 5 ), yang paling terkenal adalah IE8.

Umumnya perpustakaan akan kembali ke implementasi asli jika ada jika tidak menggunakan polyfill mereka sendiri, misalnya mari kita lihat implementasi AngularJS ( angular.js L203-257 ):

function forEach(obj, iterator, context) {
  var key;
  if (obj) {
    if (isFunction(obj)){
      for (key in obj) {
        // Need to check if hasOwnProperty exists,
        // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
        if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
          iterator.call(context, obj[key], key);
        }
      }
    } else if (obj.forEach && obj.forEach !== forEach) {
      obj.forEach(iterator, context);
    } else if (isArrayLike(obj)) {
      for (key = 0; key < obj.length; key++)
        iterator.call(context, obj[key], key);
    } else {
      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key);
        }
      }
    }
  }
  return obj;
}

Baris berikut memeriksa apakah forEachmetode ada pada objek dan apakah itu versi AngularJS atau tidak. Jika tidak menggunakan fungsi yang sudah ditentukan (versi asli):

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);
}

2. Kenyamanan

Dalam JavaScript asli Array.prototype.forEachadalah metode eksklusif untuk turunannya Array, namun sebagian besar juga Objectdapat diubah.

Karena alasan ini, banyak pembuat perpustakaan membuat fungsinya polimorfik (dapat menerima beberapa tipe sebagai input). Mari kita ambil kode AngularJS di atas dan lihat input apa yang diterima:

Fungsi :

if (isFunction(obj)){
  for (key in obj) {
    // Need to check if hasOwnProperty exists,
    // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
    if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
      iterator.call(context, obj[key], key);
    }
  }

Array (dengan dukungan native forEach):

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);

Objek seperti array termasuk Array (tanpa dukungan forEach asli), String, HTMLElement, Obyek dengan properti panjang yang valid:

} else if (isArrayLike(obj)) {
  for (key = 0; key < obj.length; key++)
    iterator.call(context, obj[key], key);

Benda:

} else {
  for (key in obj) {
    if (obj.hasOwnProperty(key)) {
      iterator.call(context, obj[key], key);
    }
  }
}

Kesimpulan

Seperti yang Anda lihat, AngularJS akan beralih ke sebagian besar Objek JavaScript, meskipun ia bekerja dengan cara yang sama seperti fungsi asli, ia menerima jenis input yang jauh lebih berbeda dan karenanya merupakan tambahan yang valid ke perpustakaan serta cara membawa fungsi ES5 ke browser lawas.

George Reith
sumber
2
Anda mungkin ingin memperbarui tautan Anda untuk menunjuk ke komit tertentu (mis. Angular.js L203-257 ) untuk referensi di masa mendatang setelah masterperubahan.
Whymarrh