Neden JavaScript çerçeveleri / kütüphaneleri zaten saf JavaScript'te var olan fonksiyonlara sahip?


60

Çerçevelerin / kütüphanelerin neden zaten kendilerine ait yardımcıları olduğunu merak ediyorum.

JQuery ve AngularJS'i alalım . Kendi eachyineleyici işlevleri var:

Ama biz var Array.prototype.forEach.

Benzer şekilde,

Ama biz JSON.parse()vanilya javascript işlevimiz var .


75
Web geliştirmenin kötü eski günlerini hatırlayan biri olarak, bu soru beni ağlatıyor.
josh3736,

3
@ josh3736 En azından hala IE6'yı desteklemeniz gerekmiyor ('tho, Neyse ki sadece "işe yaramaz, saçma gibi görünebilir" şekilde)
Izkata

12
jQuery.eachve Array.prototype.forEacheşdeğer değildir.
zzzzBov

3
Kendinize sormanız gereken şudur: VanillaJS'de bulunan fonksiyonların ne kadarı jQ ve benzeri araçlardan kaynaklanıyor? Cevap: çok . Bu şu soruyu soruyor: neden hala kullanıyoruz? Neden jQuery's'i dahil edin $.eachve yerel (ve daha hızlı) kullanmayın Array.prototype.forEach?
Elias Van Ootegem

1
@ josh3736 Sorun değil ... i.stack.imgur.com/HJs4V.jpg
Crono

Yanıtlar:


93

Çünkü bu kütüphaneler yazıldığı zaman, bazı büyük tarayıcılar bu özellikleri desteklemiyordu. Bir kez yazıldıktan ve kullanıldığında, bu özellikler pek çok uygulamayı bozmadan bu kütüphanelerden kaldırılamaz.

(Bu durumda, "büyük tarayıcı", çok sayıda kullanıcının mutlaka en son sürüme yükseltme yapmadığı, Internet Explorer gibi eski tarayıcı sürümlerini de içeren büyük pazar payına sahip bir tarayıcı anlamına gelir.)


44
$ ('marquee'). her (function () {$ (this) .append ($ ('<bgsound />', {src: "good-answer.mp3"}));});
Pierre Arlaud

36
@dirkk Son zamanlarda çıkan tarayıcıların desteklemediği değil. Herkesin yeni bir tarayıcı kullanan bir kitleye sahip olması için yeterince şanslı olmadığı.
George Reith

14
Array.prototype.forEachyalnızca diziler üzerinde yinelenir - her iki kitaplık yineleyici işlevi de diziler veya nesneler üzerinde yinelenebilir.
JoeG

3
İşlevler eski tarayıcıları desteklemek ve kütüphaneyi çağıran eski kodu desteklemek ve programcıyı yeniden yazmak istemez. IE 6 desteğini bırakmış olsanız bile, muhtemelen eski IE kopyalarını desteklemeniz gerektiğinde kullanımda olan bazı JavaScript'leriniz vardır.
Michael Shopsin

6
Bu fonksiyonların birçoğu (örneğin, jQuery.parseJSON ()) sadece tarayıcının destekleyip desteklemediğini kontrol eder ve ardından kendisini tarayıcı yöntemine ayarlar ve sadece uyumlu olmayan tarayıcılarda bir alternatif kullanır!
Josef

35

Çünkü farklı tarayıcıların , JavaScript motorlarında oluşturulan farklı uygulamaları ve özellikleri vardır . Aynı "vanilla-JS" kodu iki farklı tarayıcıda, hatta aynı tarayıcının iki farklı sürümünde farklı şekilde çalışabilir.

Popüler JS kütüphanelerinin sağladığı soyutlama katmanı bunun çevresinde bir yoldur. Sahnelerin arkasında, farklı tarayıcıların kapasiteleri ve sınırlamaları etrafında çalışır ve bunlara ek olarak birleşik, kullanımı kolay bir API sunar. Bu da, bir DOM nesnesini alma veya JSON verilerini alma gibi genel işlemlerin tutarlı, verimli ve tarayıcıda agnostik olmasını sağlar.

Bu, tarayıcı X veya Y ile çalışmak için nasıl yazılması gerektiği yerine, şimdi hangi kodun yapılması gerektiğine odaklanabilen geliştiriciler için hayatı çok kolaylaştırır.


2
"Çekirdek JS" davranışı iyi tanımlanmış ve tüm tarayıcılarda test edilmiştir.
Domenic

2
@ Dişi Sözdizimi bir yana, javascript uygulamaları tarayıcıdan tarayıcıya farklılık gösterir. Sadece birkaç tarayıcıda, hatta bazen sadece bir tanesinde bulacağınız özellikler, yöntemler, etkinlikler ve özellikler vardır.
Crono

1
Evet, tarayıcıların standart olmayan özellikleri var. Bunun, bu soruda tartışılan standart özelliklerle ilgisi yok.
Domenic

8
@Domenic Eğer "soruda tartışılan standart özellikler" derken Array.prototype.forEachve JSON.parseişlevleri kastediyorsanız, Google’da yapılan hızlı bir arama size hatalı olduğunuzu gösterir. JSONnesne IE7'de desteklenmedi ve forEachbazı Opera sürümlerinde tanımlanmadı. Ancak, jQuery gibi kütüphaneler bu sınırlamaları biliyorlardı ve etraflarında sahne arkasında çalışıyorlardı. Sanırım cevabım geçerli değil.
Crono

27

1. geriye uyumluluk

JavaScript, ECMAScript'in bir uygulamasıdır . Bu işlevlerin çoğu ECMAScript 5 (ES5) 'te tanıtıldı, ancak hala pazarda önemli bir paya sahip olan birçok eski tarayıcı bu işlevleri desteklemiyor (bkz. ECMAScript 5 uyumluluk tablosu ), bunlardan en önemlisi IE8'dir.

Genel olarak kütüphaneler, eğer kendi polyfilllerini kullanıyorlarsa mevcutsa, yerel uygulamaya geri dönecektir, örneğin, AngularJS'in uygulamasına bakalım ( 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;
}

Aşağıdaki satırlar, forEachyöntemin nesne üzerinde olup olmadığını ve AngularJS sürümü olup olmadığını kontrol eder. Değilse, önceden belirlenmiş işlevi kullanır (yerel sürüm):

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

2. Kolaylık

Yerel JavaScript'te Array.prototype.forEach, bir örneğe özgü bir yöntemdir Array, ancak çoğu Objectda yinelenebilir.

Bu nedenle birçok kütüphane yaratıcısı işlevlerini polimorfik yapar (giriş olarak çoklu türleri kabul edebilir). Yukarıdaki AngularJS kodunu alalım ve hangi girdileri kabul ettiğini görelim:

İşlevler :

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);
    }
  }

Diziler (yerel forEach desteği ile):

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

Array (yerel forEach desteği olmadan), String, HTMLElement, Geçerli bir uzunluk özelliğine sahip nesne de dahil olmak üzere dizi benzeri nesneler :

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

Nesneler:

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

Sonuç

Gördüğünüz gibi AngularJS, herhangi bir JavaScript Nesnesinin çoğunu yineleyecektir, ancak yerel işlevle aynı şekilde çalışsa da, çok daha farklı türde girdiler kabul etse de, ES5 işlevlerini getirmenin yanı sıra kitaplığa geçerli bir eklemedir eski tarayıcılara.


2
Bağlantınızı, değişiklik yapıldığında ileride başvurmak üzere belirli bir işleme (örneğin angular.js L203-257 ) işaret edecek şekilde güncellemek isteyebilirsiniz master.
Whymarrh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.