Diferencias entre Windows y Mac en la función inArray de jQuery

Muchas veces necesitamos buscar un valor dentro de un array en el cliente. Para ello utilizamos javascript, y si somos un poco mas listos, podemos enriquecer javascript con la librería jQuery.
Siempre creemos que las versiones de javascript o jQuery son las mismas para todos los entornos, ya que estan pensadas para ello, pero no es así.

La siguiente función en Mac funciona perfectamente.

  $(document).on('click', '#employees tr', function() {
      var id = this.id;
      var index = jQuery.inArray(id, aSelected);

      if ( index === -1 ) {
        aSelected.push( id );
      } else {
        aSelected.splice( index, 1 );
      }

      $(this).toggleClass('row_selected');
  });

Ahora, si ejecutamos exactamente lo mismo bajo un entorno windows, no obtenemos el mismo resultado.

El problema radica en la comparación que hace la función inArray para evaluar si el valor a buscar se encuentra en el array.

En Mac, al parecer, es menos restrictivo, esto significa que si el valor a buscar es una cadena o entero, siempre se comparan los valores como cadena, es así por lo que esta función, funciona.

En Windows no pasa esto, es algo mas restrictivo, lo que da muchas veces dolores de cabeza. En este sistema la comparación se hace con los tipos, por lo que si el valor a buscar es ‘1’, osea, una cadena, y los valores en el array son enteros, la función devolverá que no se ha encontrado el valor, ya que los tipos no coinciden.

En conclusión, acá podemos ver como la misma función tiene dos comportamientos diferentes depende el entorno.

No he ahondado más en el asunto, pero diría que el problema no es el navegador, ya que con chrome y IE8 pasa lo mismo, sino que es la plataforma.

Para solucionar el problema, tenemos que asegurarnos que los tipos que se van a comparar sean los mismos. En el caso de esta función, el valor id se espera que siempre sea un entero, pero al ser un atributo de un tag HTML es procesado como una cadena, por lo que deberíamos asegurarnos que se trata como un entero en la comparación, por lo que agregamos la función parseInt al id antes de comprarlo con el array.

A continuación como quedaría el código:

  $(document).on('click', '#employees tr', function() {
      var id = this.id;
      var index = jQuery.inArray(parseInt(id), aSelected);

      if ( index === -1 ) {
        aSelected.push( id );
      } else {
        aSelected.splice( index, 1 );
      }

      $(this).toggleClass('row_selected');
  });

Este código funciona en ambos entornos.

Espero que les haya sido de ayuda…