¿Por qué los marcos / bibliotecas de JavaScript tienen funciones que ya existen en JavaScript puro?

60

Me pregunto por qué los marcos / bibliotecas tienen sus propios ayudantes, aunque ya existen de forma nativa.

Tomemos jQuery y AngularJS . Tienen sus propias funciones de iterador each :

Pero tenemos Array.prototype.forEach .

Del mismo modo,

Pero tenemos la función JSON.parse() en JavaScript de vainilla.

    
pregunta Cihad Turhan 08.04.2014 - 01:50

3 respuestas

93

Porque cuando se escribieron esas bibliotecas, algunos de los principales navegadores no admitían esas características. Una vez escritas y utilizadas, estas funciones no pueden eliminarse de estas bibliotecas sin romper muchas aplicaciones.

(En este caso, "navegador principal" significa un navegador que aún tiene una gran participación en el mercado, que incluye versiones anteriores de navegadores como Internet Explorer, donde un gran número de usuarios no necesariamente se actualizan a la última versión).

    
respondido por el Steven Burnap 08.04.2014 - 01:57
35

Porque los distintos navegadores tienen diferentes implementaciones y características incorporadas en su motor de JavaScript. El mismo código "vanilla-JS" podría ejecutarse de manera diferente en dos navegadores diferentes, o incluso en dos versiones diferentes del mismo navegador.

La capa de abstracción proporcionada por las bibliotecas JS populares es una forma de evitar esto. Detrás de escena, funciona en función de las capacidades y limitaciones de los diferentes navegadores y ofrece una API unificada y fácil de usar. Esto, a su vez, permite que las operaciones comunes, como la obtención de un objeto DOM o la obtención de datos JSON, sean coherentes, eficientes y no tengan que ver con el navegador.

Esto hace que la vida sea mucho más fácil para los desarrolladores, que ahora pueden concentrarse en lo que debería hacer el código, en lugar de cómo debería escribirse para que funcione con el navegador X o Y.

    
respondido por el Crono 08.04.2014 - 02:04
27

1. Compatibilidad con versiones anteriores

JavaScript es una implementación de ECMAScript . La mayoría de esas funciones se introdujeron en ECMAScript 5 (ES5), sin embargo, muchos navegadores antiguos que todavía tienen una cuota de mercado suficientemente significativa no admiten estas funciones (consulte tabla de compatibilidad ECMAScript 5 ), el más notable de estos es IE8.

En general, las bibliotecas volverán a la implementación nativa si existe, de lo contrario usarán su propio polyfill, por ejemplo, veamos la implementación de 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;
}

Las siguientes líneas comprueban si el método forEach existe en el objeto y si es la versión de AngularJS o no. Si no usa la función ya especificada (la versión nativa):

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

2. Conveniencia

En JavaScript nativo, Array.prototype.forEach es un método exclusivo de una instancia de Array , sin embargo, casi cualquier Object también es iterable.

Por esta razón, muchos creadores de bibliotecas realizan sus funciones polymorphic (capaz de aceptar múltiples tipos como entrada) . Tomemos el código AngularJS de arriba y veamos qué entradas acepta:

Funciones :

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

Arrays (con soporte nativo de forEach):

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

Objetos similares a una matriz que incluyen una matriz (sin soporte nativo para cada uno), Cadena, HTMLElement, Objeto con una propiedad de longitud válida:

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

Objetos:

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

Conclusión

Como puede ver, AngularJS iterará sobre la mayoría de los objetos JavaScript, aunque funciona de la misma manera que la función nativa, acepta tipos de entrada mucho más diferentes y, por lo tanto, es una adición válida a la biblioteca, así como una forma de llevando las funciones de ES5 a los navegadores heredados.

    
respondido por el George Reith 08.04.2014 - 13:09

Lea otras preguntas en las etiquetas