¿Por qué jQuery es Indefinido?
Spanish (Español) translation by Marilu (you can also view the original English article)
Para los desarrolladores avanzados de JavaScript (y los desarrolladores de jQuery avanzado) entre nuestros lectores, este artículo no va a ser de mucha ayuda. En cambio, vamos a centrarnos en los acaban de empezar con jQuery.
Tal vez has pasado por varios tutoriales de JavaScript, construido varios pequeños sitios o proyectos que incorporan JavaScript en la página (o sitio) hasta cierto punto, y ahora estás listo para comenzar con un nuevo framework o una librería.
Si estás leyendo este tutorial, entonces supongo que usted está interesado en empezar con jQuery. O tal vez ya has comenzado con jQuery pero has encontrando un par de obstáculos que están dificultando su aprendizaje.
Tan frustrante como puede ser aprender algo nuevo, golpear un puesto de control y luego tener que repetir el proceso en líneas de código, el aspecto positivo es que las probabilidades son que sus problemas han sido resueltos por alguien más.
Esto no es necesariamente cierto para aplicaciones más complejas, pero cuando estás aprendiendo algo nuevo, no eres la primera persona que tiene una larga curva de aprendizaje. Para ello, es probable que puedas aprender algo de alguien que ha estado allí antes.
Y eso es exactamente lo que vamos a cubrir en este tutorial Específicamente, vamos a hablar del problema cuando recibas el mensaje de error:
Uncaught ReferenceError: jQuery no está definido
Entendiendo el problema
Antes de llegar a la solución, repasemos exactamente lo que está pasando. Es decir, para entender cómo llegamos a nuestra solución, necesitamos entender el problema. Solo así podremos saber cómo resolver lo que se está mostrando en la consola.



Si estás familiarizado con JavaScript, entonces sabes lo confuso que puede ser undefined, es decir, ¿hablamos del objeto global o de un valor primitivo? Eso está fuera del alcance de este post (¡no es un juego de palabras!), pero aunque no estés familiarizado con ninguna de las dos definiciones, eso no significa que no seas capaz de diagnosticar el problema.
Prepara un Sandbox
Primero, vamos a crear una página que incluya lo básico de lo que necesitamos para trabajar con la biblioteca jQuery para reproducir el error que vemos arriba.
Comienza creando el siguiente archivo HTML y guárdalo en algún lugar de tu máquina local donde puedas cargarlo fácilmente en un navegador web.
1 |
<!doctype html>
|
2 |
<html class="no-js" lang=""> |
3 |
<head>
|
4 |
<meta charset="utf-8"> |
5 |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
6 |
<title></title>
|
7 |
<meta name="description" content=""> |
8 |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
9 |
|
10 |
<link rel="stylesheet" href="css/normalize.min.css"> |
11 |
<link rel="stylesheet" href="css/main.css"> |
12 |
|
13 |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> |
14 |
|
15 |
</head>
|
16 |
<body>
|
17 |
<p>This is a basic HTML sandbox.</p> |
18 |
</body>
|
19 |
</html>
|
Ten en cuenta que estamos incluyendo algo de CSS en este archivo. Es completamente opcional, aunque si quieres seguir paso a paso este tutorial, puedes descargar un archivo de todo esto desde la parte derecha de este post.
Aunque el CSS es opcional, el JavaScript no lo es. Ten en cuenta que estamos incluyendo la biblioteca jQuery de una red de entrega de contenidos (o un CDN) para no tener que incluirla en los archivos de origen de nuestro proyecto.
A continuación, vamos a crear un archivo fuente de JavaScript que podemos utilizar para recrear el error anterior y escribir algún código de prueba para resolver el problema. Lo llamaremos main.js.
1 |
$(function() { |
2 |
|
3 |
});
|
Después de eso, incluye el archivo fuente en tu documento HTML de manera que el archivo final tenga este aspecto:
1 |
<!doctype html>
|
2 |
<html class="no-js" lang=""> |
3 |
<head>
|
4 |
<meta charset="utf-8"> |
5 |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
6 |
<title></title>
|
7 |
<meta name="description" content=""> |
8 |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
9 |
|
10 |
<link rel="stylesheet" href="css/normalize.min.css"> |
11 |
<link rel="stylesheet" href="css/main.css"> |
12 |
|
13 |
<script src="js/main.js"></script> |
14 |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> |
15 |
|
16 |
</head>
|
17 |
<body>
|
18 |
<p>This is a basic HTML sandbox.</p> |
19 |
</body>
|
20 |
</html>
|
Ahora deberías poder cargar la página en tu navegador y ver algo casi exactamente como la imagen de la consola compartida arriba.
Verifica que tu JavaScript está cargado
Antes de seguir adelante, vamos a asegurarnos de que el archivo JavaScript está cargado correctamente. Para ello, configuraremos una simple alerta para que se muestre un mensaje cada vez que se cargue la página en el navegador.



Para ver esta pantalla, haz el siguiente cambio en tu archivo fuente de JavaScript:
1 |
$(function() { |
2 |
alert( 'JavaScript Loaded!' ); |
3 |
});
|
A continuación, asegúrate de reordenar los archivos de JavaScript, pasando de:
1 |
<script src="js/main.js"></script> |
2 |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> |
A:
1 |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> |
2 |
<script src="js/main.js"></script> |
Hablaremos más sobre esto en un rato.
En este punto, refresca la página. Asumiendo que todo ha ido bien hasta este punto, entonces deberías ver el diálogo como se muestra en la imagen de arriba. Si eso no funciona, revisa el código de arriba (o descarga los archivos adjuntos a este tutorial) y asegúrate de que tienes todo cargado correctamente.
Reproduciendo el problema
Ahora que tenemos el entorno de trabajo preparado para poder empezar a explorar el problema en profundidad, echemos un vistazo a algunos de los posibles problemas que se pueden dar cuando se trabaja con jQuery.
1. jQuery se carga después de tu código
Siempre que optas por usar jQuery en un proyecto, esto significa que jQuery se convierte en una dependencia para tu trabajo. Y siempre que trabajes con dependencias, generalmente necesitas asegurarte de que se cargan antes que tu código para que éste pueda beneficiarse de ello.
Si te fijas en el primer trozo de código de arriba, nuestro archivo JavaScript se carga antes que jQuery, así que cualquier cosa que queramos hacer con jQuery no se puede hacer en realidad. La razón por la que estás viendo el mensaje de error undefined que discutimos antes es porque jQuery no está literalmente definido dentro del contexto de tu código.
Es decir, tu código no tiene ni idea de que jQuery existe porque jQuery está cargado después de tu código. Por suerte, la solución a esto es sencilla. Simplemente cambia el orden en el que se cargan los archivos, es decir, coloca jQuery sobre tu archivo fuente, y luego intenta ejecutar el código una vez más.
Después del cambio, el HTML completo debería verse así:
1 |
<!doctype html>
|
2 |
<html class="no-js" lang=""> |
3 |
<head>
|
4 |
<meta charset="utf-8"> |
5 |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
6 |
<title></title>
|
7 |
<meta name="description" content=""> |
8 |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
9 |
|
10 |
<link rel="stylesheet" href="css/normalize.min.css"> |
11 |
<link rel="stylesheet" href="css/main.css"> |
12 |
|
13 |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> |
14 |
<script src="js/main.js"></script> |
15 |
|
16 |
</head>
|
17 |
<body>
|
18 |
<p>This is a basic HTML sandbox.</p> |
19 |
</body>
|
20 |
</html>
|
Tu código debería funcionar y la consola no debería mostrar ningún error. Este es probablemente el problema más fácil de resolver, pero es probablemente uno de los errores menos comunes de ver, ya que generalmente se asume que jQuery tendrá que ser cargado primero.
2. Un plugin o archivo conflictivo
Cuando se trabaja con jQuery, a veces a los desarrolladores les gusta modificar la función $ para que no entre en conflicto con otra cosa que utilice su código fuente.
Específicamente, jQuery es el nombre de la función dentro del código fuente de jQuery. La biblioteca usa $ como sinónimo o atajo, ya que es probable que se use muy a menudo. Hace que el código sea más fácil de escribir y más fácil de leer.
No hay conflictos
Pero no es el único código JavaScript que utiliza esa función y a veces los desarrolladores tendrán que utilizar una función diferente o renunciar al $ por otro fragmento de código fuente. Para ello, pueden terminar usando jQuery.noConflict().
Directamente desde el API:
Muchas bibliotecas de JavaScript usan$como nombre de función o de variable, al igual que jQuery. En el caso de jQuery,$es solo un alias parajQuery, así que toda la funcionalidad está disponible sin usar$.
Si necesitas usar otra librería de JavaScript junto a jQuery, devuelve el control de$a la otra librería con una llamada a$.noConflict(). Las referencias antiguas de$se guardan durante la inicialización de jQuery;noConflict()simplemente las restaura.
Así que en algún lugar del código que has incluido, hay una posibilidad de que otro desarrollador haya hecho una llamada a esta función. Por lo tanto, la función $ no será accesible. Podría estar llamando a una función que no sea la propia jQuery, o podría estar llamando a una función que está undefined.
En nuestro caso, nos interesa lo último. Para abordar esto, podemos intentar un par de soluciones. Primero, podemos intentar recuperar el acceso a la función $ simplemente llamando a jQuery.noConflict() una vez más. Aunque esto puede resolver el problema, también puede dar lugar a otro problema que existe si se incluye otro marco, biblioteca o algún otro módulo con tu código.
Para ello, solo recomiendo usar esto cuando estés absolutamente seguro de que sabes lo que haces y que no afectará a otros marcos.
Determinar $ correctamente
¿Pero qué pasa si no sabes que no afectará a otros marcos? ¿Y luego qué? En este caso, tienes la oportunidad de inicializar tu código de manera que empiece con la función básica de jQuery y luego usar el $ para ampliar la función de shortcut en el contexto de tu propio código.
¿Suena complicado? No te preocupes. No está mal. Editamos nuestro archivo fuente de JavaScript para que contenga lo siguiente:
1 |
(function( $ ) { |
2 |
'use strict'; |
3 |
|
4 |
$(function() { |
5 |
alert( 'JavaScript Loaded!' ); |
6 |
});
|
7 |
|
8 |
})( jQuery ); |
Muy bien, esto es lo que está pasando:
- Estamos declarando una función anónima que acepta un solo argumento (en nuestro caso,
jQuery). - La función será pasada y referenciada por
$y será contemplada solo dentro del contexto de nuestra función anónima.
Esto significa que somos libres de usar la función $ como queramos, sin interferir con ninguna otra implementación de esa función en particular. De hecho, por si sirve de algo, esta es la forma de hecho de configurar tu código basado en jQuery.
No todos lo hacen de esta manera, pero es una forma muy común y muy segura de manejarlo para poder evitar todo el mensaje de error undefined.
3. ¿Hay más?
Por supuesto. Pero el desafío es averiguar cómo cubrirlos todos. La verdad es que no sé si es realmente posible porque, en algún momento, la complejidad de los proyectos web se hace tan grande que rastrear dónde existe el problema puede ser difícil.
Además, cambiar jQuery para hacer lo que quieres que haga podría terminar rompiendo algo más (lo que obviamente nunca es algo bueno).
En su lugar, es mejor atenerse a lo que sabemos que es seguro, como el enfoque de la función anónima mencionado anteriormente, y no abusar de cosas como el método noConflict(). Después de todo, parte del buen desarrollo no es solo jugar bien con el código de otras personas, sino escribir código con el que otros pueden jugar bien también.
Conclusión
Como se ha señalado anteriormente, hay una serie de cosas diferentes que podrían desencadenar el mensaje jQuery is undefined en tu consola. Hemos tratado de examinar varios de los problemas más comunes en los ejemplos anteriores.
Dicho esto, es difícil ser exhaustivo porque es casi imposible cubrir todas las combinaciones y permutaciones que puedes haber establecido en tu proyecto. Tal vez estás usando una biblioteca conflictiva, tal vez es un plugin mal escrito, o tal vez solo hay dependencias que no están ordenadas adecuadamente.
Sea cual sea el caso, es de esperar que esto ayude a explicar cuál es el problema y algunas formas de avanzar en el diagnóstico. Si tu solución no se ha esbozado aquí, entonces por favor, no dudes en dejarla en los comentarios.
Además, si tienes alguna otra pregunta, no dudes en dejarla en los comentarios de abajo y trataré de responderla lo mejor posible.



