2010-10-13 18 views
22

¿Cuáles son algunos de los "errores" comunes de Javascript y/o jQuery que ha visto o ha pasado por alto?Javascript/jQuery "Gotchas"

A modo de ejemplo, se señaló a mí esta mañana que hay que tener cuidado con la raíz cuando se hace parseInt(), porque si su cadena comienza con un 0, la raíz será por defecto 8.

+2

Marcar como CW si va a sobrevivir al cierre ... –

+1

Definitivamente debería ser CW. – Pointy

+1

Gracias por la (s) propina (s). – Ender

Respuesta

7

i se lo recomendaría a leer todo http://wtfjs.com/

+2

Nice site. Explica una de mis preguntas por cierto. : P – BrunoLM

+0

primera pregunta es sobre mi sitio y blog! http://www.typeofnan.com: p – jAndy

0

Javascript

parseInt('0aaa') //still returns 0 
parseFloat('0.aaa') //still returns 0 

Este los más de un factor Uy. Cuando escribo una declaración de cambio, se me conoce que olvide poner un descanso en la declaración, lo que causa problemas.

var myvar = '1' 
switch (myvar) { 
    case '1': 
    alert(myvar); 
    case '2': 
    alert(myvar); 
    break; 
} 

porque se me olvidó la ruptura de la case '1' que recibirá la alerta dos veces.

+0

el interruptor no es un JS/JQUERY 'gotchas'. Esto también es posible en otros idiomas C/C++/C# etc. – RvdK

+0

@PoweRoy ... Lo sé ... es exactamente por eso que dije que era "más de un factor oops" –

+0

@PoweRoy: esquina de Nitpicker - es un [ error en tiempo de compilación] (http://msdn.microsoft.com/en-us/library/06tc147t.aspx) para que el control caiga a través de una etiqueta de mayúscula en C#. En otras palabras, el código de John no se compilaría si fuera C#. – josh3736

12

Reemplazando .round()/.floor() o .ceil() con ~~ para recortar decimales es muy guapo.

En lugar de

Math.floor(Math.random() * 100); 

que hacen

~~(Math.random() * 100); 

Es sólo más corto y tiene un mejor rendimiento, incluso!

+1

Eso es más una propina/truco que un gotcha, ¡pero sigue siendo genial! – Ender

+0

Pude ver '.floor()' y '.ceil()' si agrega 1, pero no parece un gran sustituto para '.round()'. Tal vez esa es la parte * gotcha *? ; o) – user113716

+0

@patrick: bueno en el contexto solo para deshacerse de los decimales, de hecho lo es. – jAndy

2

El libro de Douglas Crockford JavaScript: The Good Parts es una lectura excelente sobre el tema. Hay también las partes malas y terribles de Javascript en él :)

9

El alcance de 'esto'

Consideremos el siguiente ejemplo:

function myClass(message) { 
    this.message = message; 
    $('button').click(function(){ 
    this.onClick(); 
    });  
} 

myClass.prototype.onClick = function() { 
    alert(this.message); 
} 

Por supuesto, la línea 3 no funciona : this funciona por función, y la función definida en la línea 2 tendrá el botón seleccionado como this en lugar de la instancia de myClass. Hay una versión aún más disimulados:

function myClass(message) { 
    this.message = message; 
    $('button').click(this.onClick);  
} 

myClass.prototype.onClick = function() { 
    alert(this.message); 
} 

Este llama a la función correcta, pero this seguiría siendo el botón (porque this está determinado por la persona que llama, no por el hecho de que usted es un miembro de la función).La solución correcta es utilizar una variable intermedia, tal como self, para aplicar reglas de alcance sanos a this:

function myClass(message) { 
    this.message = message; 
    var self = this; 
    $('button').click(function() { self.onClick(); });  
} 

Tipo de colada

[] == ![] evalúa a verdadero por razones oscuras

Arrays y Propiedades

ElLa propiedad 10 solo funciona para las claves enteras en las matrices. Por ejemplo:

var a = [];  // a.length == 0 
a[0] = 'first'; // a.length == 1 
a['1'] = 'second'; // a.length == 2 
a['x'] = 'third'; // a.length == 2 <-- 'x' does not count 

Si bien sobre este tema, for(in) trabajos sobre matrices, pero atraviesa todos propiedades definidas en la matriz. Esto significa que su código JavaScript que usa for(in) para iterar a través de matrices dejará de funcionar repentinamente en ciertos navegadores cuando agregue ExtJS a su proyecto, porque ExtJS define Array.prototype.filter si no está presente (esto se conoce como parche de mono). Dado que ahora filter es una propiedad personalizada de cada objeto de matriz, todos sus bucles también se repiten a través de él. Auge.

La manera limpia de iterar a través de una matriz es usar la longitud y un incremento para el ciclo. O jQuery's $.each().

8

La mayor WTF que he encontrado en Javascript debe ser String.replace.

Tome este código, por ejemplo:

"An,example,of,a,comma,separated,sentence".replace(',', ' '); 

Esto produce una sentencia muy bien separados por espacios en lugar, ¿verdad?

Para mi gran sorpresa: no, no es así. Solo reemplaza la primera coma con un espacio, dejando el resto sin tocar. Si desea hacer una sustitución real, debe usar .replace(/,/g, ' ').

Por qué el método no se llama 'replaceFirst' es una incógnita.

+0

de hecho, una idea falsa común (* en realidad desviación de la norma *) –

+0

El truco es que de acuerdo con los documentos originales de Netscape que tengo, la firma de este método es 'String.replace (regexp, newText)' En muchos casos, se usa "String" simple como primer parámetro, por lo que el concepto de bandera global para la expresión regular se pasa por alto por completo. – scunliffe

+1

Casi cada rutina de reemplazo de cadenas que he visto ha tenido el modo "solo el primero" como valor predeterminado. Como ejemplo, el comando "vi" replace, y todas las variantes de Unix/Linux como "sed", requieren un sufijo "g" para hacer un "replace all". La biblioteca Java tiene "replace" y "replaceAll", con la misma semántica (en cualquier caso, en lo que respecta a la política de reemplazo). – Pointy

1

Variable de alcance y variables de bucle es definitivamente un "gotcha". Esto ocurre muchas veces en la asignación de controladores de eventos en un bucle:

var lis= document.getElementsByTagName('li'), 
    imgs = document.getElementsByTagName('img'); 
for (i = 0; i < elements.length; i++) 
{ 
    elements[i].onclick = function() { 
     imgs[i].src = elements[i].innerHTML; 
    } 
} 

En el momento de la ejecución, imgs[i] estarán indefinidos, arrojando un error al intentar acceder a imgs[i].src. Lo mismo para elements[i] y su innerHTML.

+0

Muy cierto, ayer respondí una pregunta donde esta fue la causa del problema. – Ender

1

globales implícitas son uno grande:

var x = 12, y = 14; 
function addOne(num) 
{ 
    x = num + 1; // since this is not declared with 'var', it is implied global 
    return x; 
} 

alert(addOne(y)); // alerts '15' 
alert(addOne(x));  // alerts '16' 

Es un ejemplo sencillo, y poco realista, pero demuestra el problema muy bien.

2

Un muy buen artículo fue recientemente por Elijah Manor en su blog, Enterprise jQuery. Está escrito en "errores" de Javascript para desarrolladores de C#. Es una serie parcial y hay una serie de buenos puntos que también "harán" que las personas se familiaricen con otros idiomas.

Échale un vistazo aquí: How Good C# Habits can Encourage Bad JavaScript Habits.

+1

Gracias por la mención. Me alegra que hayas disfrutado el artículo. El post # 2 salió hoy y una tercera publicación debería estar disponible la próxima semana. –

+1

@Elijah - No hay problema, y ​​gracias por una gran serie de artículos. Como desarrollador de C# que ha estado haciendo mi parte justa de JavaScript recientemente, fue útil (particularmente el material falso). – JasCav

5

La declaración return debe tener un valor inmediatamente después de ella, o por lo menos a partir de la misma línea:

return 4; // returns 4 
return {}; // returns an empty object 
return { // returns an empty object 
};   
return  // returns undefined 
{ 
}; 
3

Ajax obtiene/mensajes a un URI estática pueden quedar almacenado en caché por el IE. Por lo tanto, debe agregar un parámetro cambiante, una forma rápida y fácil de agregar new Date().getTime()

+2

O puede definir: $ .ajaxSetup ({cache: false}); que agregará la fecha/hora al final de cualquier Ajax get/posts. – Sphvn

Cuestiones relacionadas