10 rarezas y secretos sobre JavaScript

 

 

 

  • Register!
  • Typography Masterclass, with Elliot Jay Stocks

  • Índice
    1. Tipos de datos y definiciones
      1. 1. Nulo es un objeto
      2. 2. NaN es un número
      3. 3. Una matriz sin claves == Falso (Acerca de Verdad y Falso)
    2. Expresiones regulares
      1. 4. reemplazar() puede aceptar una función de devolución de llamada
      2. 5. Expresiones regulares: más que simplemente unir y reemplazar
    3. Funciones y alcance
      1. 6. Puedes falsificar el alcance
      2. 7. Las funciones pueden ejecutarse solas
    4. El navegador
      1. 8. Firefox lee y devuelve colores en RGB, no en hexadecimal
    5. Misceláneas
      1. 9. 0,1 + 0,2 !== 0,3
      2. 10. Lo indefinido se puede definir
    6. Recursos adicionales
      1. Otras lecturas

    Una colección de curiosidades y secretos bien guardados de JavaScript para desarrolladores intermedios. Andy Croxall le brinda una idea de cómo estas rarezas pueden ser útiles para su código.

     

    JavaScript. Extraño y hermoso al mismo tiempo, es seguramente el lenguaje de programación que habría inventado Pablo Picasso. Null es aparentemente un objeto, una matriz vacía es aparentemente igual a falsey las funciones se intercambian como si fueran pelotas de tenis.

    Este artículo está dirigido a desarrolladores intermedios que sientan curiosidad por JavaScript más avanzado. Es una colección de rarezas y secretos bien guardados de JavaScript. Es de esperar que algunas secciones le brinden una idea de cómo estas curiosidades pueden ser útiles para su código, mientras que otras secciones son material puro de WTF. Entonces empecemos.

    Tipos de datos y definiciones

    1. Nulo es un objeto

    Comencemos con la rareza de JavaScript favorita de todos, por muy conocida que sea. Null es aparentemente un objeto que, en lo que respecta a las contradicciones, está a la altura de los mejores. ¿Nulo? ¿Un objeto? "Seguramente, la definición de nulo es la ausencia total de valor significativo ", dices. Estarías en lo cierto. Pero así son las cosas. Aquí está la prueba:

    alert(typeof null); //alerts 'object'

    A pesar de esto, null no se considera una instancia de un objeto. (En caso de que no lo sepas, los valores en JavaScript son instancias de objetos base. Entonces, cada número es una instancia del Numberobjeto, cada objeto es una instancia del Objectobjeto, y así sucesivamente). Esto nos devuelve a la cordura, porque si nulo es la ausencia de valor, entonces obviamente no puede ser una instancia de nada. Por lo tanto, lo siguiente se evalúa como false:

    alert(null instanceof Object); //evaluates false

    2. NaN es un número

    ¿Pensabas que ser nulo un objeto era ridículo? Intente lidiar con la idea de NaN– “no un número” – ¡ser un número! ¡Además, NaNno se considera igual a sí mismo! ¿Ya te duele la cabeza?

    alert(typeof NaN); //alerts 'Number'alert(NaN === NaN); //evaluates false

    De hecho no NaNes igual a nada . La única forma de confirmar que algo es NaNa través de la función isNaN().

    3. Una matriz sin claves == Falso (Acerca de Verdad y Falso)

    Aquí hay otra rareza de JavaScript muy querida:

    alert(new Array() == false); //evaluates true

    Para comprender lo que está sucediendo aquí, es necesario comprender los conceptos de verdad y falsedad . Estos son una especie de verdadero/falso, lo que te enojará un poco si te especializas en lógica o filosofía.

    He leído muchas explicaciones sobre qué son verdadero y falso, y creo que la más fácil de entender es esta: en JavaScript, cada valor no booleano tiene un indicador booleano incorporado que se invoca cuando se le pide al valor que se comporte. como un booleano; como, por ejemplo, cuando lo comparas con un booleano.

     

    Debido a que las manzanas no se pueden comparar con las peras, cuando se le pide a JavaScript que compare valores de diferentes tipos de datos, primero los " coacciona " a un tipo de datos común. False, zero, null, undefined, cadenas vacías y NaNtodas terminan convirtiéndose false, no de forma permanente, solo para la expresión dada. Un ejemplo al rescate:

    var someVar = 0;alert(someVar == false); //evaluates true

    Aquí, intentamos comparar el número 0con el booleano false. Debido a que estos tipos de datos son incompatibles, JavaScript fuerza secretamente nuestra variable a su equivalente verdadero o falso , que en el caso de 0(como dije anteriormente) es falso.

    Quizás hayas notado que no incluí matrices vacías en la lista de falsificaciones anterior. Las matrices vacías son cosas curiosas: en realidad se evalúan como verdaderas pero , en comparación con un booleano, se comportan como falsas. ¿Confundido todavía? Con buena causa. ¿Otro ejemplo quizás?

    var someVar = []; //empty arrayalert(someVar == false); //evaluates trueif (someVar) alert('hello'); //alert runs, so someVar evaluates to true

    Para evitar la coerción, puede utilizar el operador de comparación de valores y tipos , ===, (a diferencia de ==, que compara solo por valor). Entonces:

    var someVar = 0;alert(someVar == false); //evaluates true – zero is a falsyalert(someVar === false); //evaluates false – zero is a number, not a boolean

    Uf. Como probablemente ya habrás deducido, este es un tema amplio y recomiendo leer más sobre él, particularmente sobre la coerción de datos, que, si bien no es exclusivamente un concepto de JavaScript, es no obstante prominente en JavaScript.

    Hablo más sobre el concepto de veracidad y falsedad y coerción de datos aquí. Y si realmente quiere profundizar en lo que sucede internamente cuando se le pide a JavaScript que compare dos valores, consulte la sección 11.9.3 de la especificación del documento ECMA-262.

    Expresiones regulares

    4. reemplazar() puede aceptar una función de devolución de llamada

    Este es uno de los secretos mejor guardados de JavaScript y llegó en la versión 1.3. La mayoría de los usos de replace()se parecen a esto:

    alert('10 13 21 48 52'.replace(/d+/g, '*')); //replace all numbers with *

    Este es un reemplazo simple: una cadena, un asterisco. Pero ¿qué pasaría si quisiéramos tener más control sobre cómo y cuándo se producen nuestros reemplazos? ¿Qué pasaría si quisiéramos reemplazar solo los números menores de 30? Esto no se puede lograr solo con expresiones regulares (después de todo, se trata de cadenas, no de matemáticas). Necesitamos saltar a una función de devolución de llamada para evaluar cada coincidencia .

    alert('10 13 21 48 52'.replace(/d+/g, function(match) { return parseInt(match) 30 ? '*' : match;}));

    Para cada coincidencia realizada, JavaScript llama a nuestra función y pasa la coincidencia a nuestro argumento de coincidencia. Luego, devolvemos el asterisco (si el número coincidente es inferior a 30) o la coincidencia misma (es decir, no debería realizarse ninguna coincidencia).

     

    5. Expresiones regulares: más que simplemente unir y reemplazar

    Muchos desarrolladores intermedios de JavaScript se las arreglan sólo matchcon replaceexpresiones regulares. Pero JavaScript define más métodos que estos dos.

    De particular interés es test(), que funciona igual matchexcepto que no devuelve coincidencias: simplemente confirma si un patrón coincide . En este sentido, es computacionalmente más ligero.

    alert(/w{3,}/.test('Hello')); //alerts 'true'

    Lo anterior busca un patrón de tres o más caracteres alfanuméricos y, como la cadena Hellocumple con ese requisito, obtenemos true. No obtenemos el partido real, sólo el resultado.

    También es de destacar el RegExpobjeto mediante el cual se pueden crear expresiones regulares dinámicas, en lugar de estáticas. La mayoría de las expresiones regulares se declaran en forma corta (es decir, entre barras diagonales, como hicimos anteriormente). Sin embargo, de esa manera no se pueden hacer referencia a variables, por lo que es imposible crear patrones dinámicos . Sin embargo, con RegExp(), puedes.

    function findWord(word, string) { var instancesOfWord = string.match(new RegExp('b'+word+'b', 'ig')); alert(instancesOfWord);}findWord('car', 'Carl went to buy a car but had forgotten his credit card.');

    Aquí, estamos creando un patrón dinámico basado en el valor del argumento word. La función devuelve el número de veces que wordaparece en la cadena como una palabra por derecho propio (es decir, no como parte de otras palabras). Entonces, nuestro ejemplo regresa caruna vez, ignorando los cartokens en las palabras Carly card. Esto lo fuerza comprobando un límite de palabra ( b) a cada lado de la palabra que estamos buscando.

    Debido RegExpa que se especifican como cadenas, no mediante sintaxis de barra diagonal, podemos usar variables para crear el patrón. Sin embargo, esto también significa que debemos aplicar doble escape a cualquier carácter especial, como hicimos con el carácter de límite de palabra.

    Funciones y alcance

    6. Puedes falsificar el alcance

    El alcance en el que se ejecuta algo define qué variables son accesibles. JavaScript independiente (es decir, JavaScript que no se ejecuta dentro de una función) opera dentro del alcance global del windowobjeto, al que todo tiene acceso; mientras que las variables locales declaradas dentro de funciones solo son accesibles dentro de esa función, no fuera.

    var animal = 'dog';function getAnimal(adjective) { alert(adjective+' '+this.animal); }getAnimal('lovely'); //alerts 'lovely dog';

    Aquí, nuestra variable y función se declaran en el ámbito global (es decir, en window). Debido a que esto siempre apunta al alcance actual, en este ejemplo apunta a window. Por tanto, la función busca window.animaly encuentra. Hasta ahora todo normal. Pero en realidad podemos engañar a nuestra función haciéndole creer que se está ejecutando en un ámbito diferente , independientemente de su propio ámbito natural. Hacemos esto llamando a su método incorporado call(), en lugar de a la función en sí:

     

    var animal = 'dog';function getAnimal(adjective) { alert(adjective+' '+this.animal); };var myObj = {animal: 'camel'};getAnimal.call(myObj, 'lovely'); //alerts 'lovely camel'

    Aquí, nuestra función no se ejecuta una y windowotra vez, sino myObjespecificada como el primer argumento del método de llamada. Básicamente, call()pretende que nuestra función es un método de myObj(si esto no tiene sentido, es posible que desees leer sobre el sistema de herencia prototípica de JavaScript). Tenga en cuenta también que cualquier argumento que pasemos call()después del primero se pasará a nuestra función; por lo tanto, lo pasaremos lovelycomo nuestro adjectiveargumento.

    He escuchado a desarrolladores de JavaScript decir que han pasado años sin necesitar usar esto, sobre todo porque un buen diseño de código garantiza que no necesites este humo y espejos. No obstante, es ciertamente interesante.

    Además, apply()hace el mismo trabajo que call(), excepto que los argumentos de la función se especifican como una matriz, en lugar de como argumentos individuales. Entonces, el ejemplo de uso anterior apply()se vería así:

    getAnimal.apply(myObj, ['lovely']); //func args sent as array

    7. Las funciones pueden ejecutarse solas

    No se puede negar:

    (function() { alert('hello'); })(); //alerts 'hello'

    La sintaxis es bastante simple: declaramos una función e inmediatamente la llamamos tal como llamamos a otras funciones, con ()sintaxis. Quizás se pregunte por qué haríamos esto. Parece una contradicción en los términos: una función normalmente contiene código que queremos ejecutar más tarde, no ahora, de lo contrario no habríamos puesto el código en una función.

    Un buen uso de las funciones autoejecutables (SEF) es vincular los valores actuales de las variables para su uso dentro del código retrasado, como devoluciones de llamadas a eventos, tiempos de espera e intervalos. Aquí está el problema:

    var someVar = 'hello';setTimeout(function() { alert(someVar); }, 1000);var someVar = 'goodbye';

    Los novatos en los foros invariablemente preguntan por qué alertdice y no . La respuesta es que la función de devolución de llamada es precisamente eso, una devolución de llamada, por lo que no evalúa el valor de hasta que se ejecuta. Y para entonces, hace mucho que ya fue sobrescrito por .timeoutgoodbyehellotimeoutsomeVarsomeVargoodbye

    Los SEF proporcionan una solución a este problema. En lugar de especificar implícitamente la devolución de llamada de tiempo de espera como lo hacemos anteriormente, la devolvemos desde un SEF, al que pasamos el valor actual de someVarcomo argumento. Efectivamente, esto significa que pasamos y aislamos el valor actual de someVar, protegiéndolo de lo que le suceda a la variable real someVara partir de entonces . Esto es como tomar una fotografía de un automóvil antes de volver a pintarlo; la foto no se actualizará con el color repintado; Siempre mostrará el color del automóvil en el momento en que se tomó la foto.

     

    var someVar = 'hello';setTimeout((function(someVar) { return function() { alert(someVar); }})(someVar), 1000);var someVar = 'goodbye';

    Esta vez, alerta hello, como se desea, porque está alertando a la versión aislada de someVar(es decir, el argumento de la función, no la variable externa).

    El navegador

    8. Firefox lee y devuelve colores en RGB, no en hexadecimal

    Nunca entendí realmente por qué Mozilla hace esto. Seguramente se da cuenta de que cualquiera que interrogue los colores calculados a través de JavaScript está interesado en el formato hexadecimal y no en RGB. Para aclarar, aquí hay un ejemplo:

    Hello, world!scriptvar ie = navigator.appVersion.indexOf('MSIE') != -1;var p = document.getElementById('somePara');alert(ie ? p.currentStyle.color : getComputedStyle(p, null).color);/script

    Si bien la mayoría de los navegadores alertarán ff9900, Firefox devuelve rgb(255, 153, 0)el equivalente RGB. Existen muchas funciones de JavaScript para convertir RGB a hexadecimal.

    Tenga en cuenta que cuando digo color calculado, me refiero al color actual, independientemente de cómo se aplique al elemento . Compare esto con estilo, que lee sólo las propiedades de estilo que se establecieron implícitamente en el atributo de estilo de un elemento. Además, como habrás notado en el ejemplo anterior, IE tiene un método diferente para detectar estilos calculados desde otros navegadores.

    Además, css()el método de jQuery abarca este tipo de detección computarizada y devuelve estilos sin importar cómo se aplicaron a un elemento: implícitamente o mediante herencia o lo que sea. Por lo tanto, rara vez necesitarás los archivos nativo getComputedStyley currentStyle.

    Misceláneas

    9. 0,1 + 0,2 !== 0,3

    Ésta es una rareza no sólo en JavaScript; En realidad, es un problema predominante en la informática y afecta a muchos idiomas. La salida de esto es 0.30000000000000004.

    Esto tiene que ver con una cuestión llamada precisión de las máquinas . Cuando JavaScript intenta ejecutar la línea anterior, convierte los valores a sus equivalentes binarios.

    Aquí es donde empieza el problema. 0,1 no es realmente 0,1 sino más bien su equivalente binario, que es un valor cercano (pero no idéntico) . En esencia, tan pronto como escribes los valores, están condenados a perder su precisión. Es posible que simplemente quisieras dos decimales simples, pero lo que obtienes, como señala Chris Pine, es aritmética binaria de punto flotante. Algo así como querer traducir tu texto al ruso pero obtenerlo en bielorruso. Parecidos, pero no iguales.

    Hay más cosas aquí, pero están más allá del alcance de este artículo (sin mencionar las capacidades matemáticas de este autor).

    Las soluciones alternativas para este problema son las favoritas en los foros de desarrolladores y de informática. Su elección, hasta cierto punto, se reduce al tipo de cálculos que esté haciendo. Los pros y los contras de cada uno están fuera del alcance de este artículo, pero la elección común es entre las siguientes:

    1. Convertir a números enteros y calcularlos, y luego volver a convertir a decimales; o
    2. Modificar su lógica para permitir un rango en lugar de un resultado específico .

    Entonces, por ejemplo, en lugar de...

    var num1 = 0.1, num2 = 0.2, shouldEqual = 0.3;alert(num1 + num2 == shouldEqual); //false

    … haríamos esto:

    alert(num1 + num2 shouldEqual - 0.001 num1 + num2 shouldEqual + 0.001); //true

    Traducido, esto dice que debido a que 0,1 + 0,2 aparentemente no es 0,3, verifica que sea más o menos 0,3, específicamente, dentro de un rango de 0,001 a cada lado. El inconveniente obvio es que, para cálculos muy precisos, esto arrojará resultados inexactos.

    10. Lo indefinido se puede definir

    Bien, terminemos con uno tonto y bastante intrascendente. Por extraño que parezca, undefineden realidad no es una palabra reservada en JavaScript, aunque tiene un significado especial y es la única forma de determinar si una variable no está definida. Entonces:

    var someVar;alert(someVar == undefined); //evaluates true

    Hasta ahora todo normal. Pero:

    undefined = "I'm not undefined!";var someVar;alert(someVar == undefined); //evaluates false!

    También puede consultar la lista de Mozilla de todas las palabras reservadas en JavaScript para referencia futura.

    Recursos adicionales

    • Explicación de las rarezas de JavaScript. Comparando.
    • Errores de JavaScript
    • Aún más sobre trampas
    • reemplazar() funciones de devolución de llamada

    Otras lecturas

    • Creación de perfiles de JavaScript con las herramientas para desarrolladores de Chrome
    • Escribir JavaScript rápido y con memoria eficiente
    • Potentes consejos, herramientas y trucos de flujo de trabajo para diseñadores web
    • El futuro de las herramientas de construcción frontend

    (al, il, mrn)Explora más en

    • Codificación
    • javascript
    • Matemáticas
    • Errores
    • Esenciales





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    10 rarezas y secretos sobre JavaScript

    10 rarezas y secretos sobre JavaScript

    Register! Typography Masterclass, with Elliot Jay Stocks Índice Tipos de datos y definiciones

    programar

    es

    https://aprendeprogramando.es/static/images/programar-10-rarezas-y-secretos-sobre-javascript-773-0.jpg

    2024-04-04

     

    10 rarezas y secretos sobre JavaScript
    10 rarezas y secretos sobre JavaScript

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20