¿Qué "características ocultas" de JavaScript crees que todo programador debería saber?
Después de haber visto la excelente calidad de las respuestas a las siguientes preguntas, pensé que era hora de pedirle JavaScript.
- Características ocultas de HTML
- Características ocultas de CSS
- Características ocultas de PHP
- Características ocultas de ASP.NET
- Características ocultas de C #
- Características ocultas de Java
- Características ocultas de Python
A pesar de que JavaScript es posiblemente el lenguaje más importante del lado del cliente en este momento (solo pregúntele a Google) es sorprendente lo poco que la mayoría de los desarrolladores web aprecian lo poderoso que realmente es.
javascript
hidden-features
Binoj Antony
fuente
fuente
Respuestas:
No necesita definir ningún parámetro para una función. Simplemente puede usar el
arguments
objeto tipo matriz de la función .fuente
arguments
objeto hace que llamar a una función sea mucho más lento, por ejemplo. argumentos if (falsos); lastimará perf.arguments.callee
se está desaprobando.Podría citar la mayor parte del excelente libro de Douglas Crockford JavaScript: The Good Parts .
Pero tomaré solo uno para usted, siempre use
===
y en!==
lugar de==
y!=
==
No es transitivo. Si lo usa===
, daría falso para todas estas declaraciones como se esperaba.fuente
==
es'\n\t\r ' == 0
=>true
...: DLas funciones son ciudadanos de primera clase en JavaScript:
Las técnicas de programación funcional se pueden usar para escribir javascript elegante .
En particular, las funciones se pueden pasar como parámetros, por ejemplo, Array.filter () acepta una devolución de llamada:
También puede declarar una función "privada" que solo existe dentro del alcance de una función específica:
fuente
new Function()
es tan malo comoeval
. No utilice.Puede usar el operador in para verificar si existe una clave en un objeto:
Si encuentra los literales de los objetos demasiado feos, puede combinarlos con la sugerencia de función sin parámetros:
fuente
Asignación de valores predeterminados a variables
Puede usar el operador lógico o
||
en una expresión de asignación para proporcionar un valor predeterminado:La
a
variable obtener el valor dec
sólo sib
es Falsy (si esnull
,false
,undefined
,0
,empty string
, oNaN
), de lo contrarioa
obtendrá el valor deb
.Esto suele ser útil en funciones, cuando desea dar un valor predeterminado a un argumento en caso de que no se proporcione:
Ejemplo de reserva de IE en controladores de eventos:
Las siguientes características del lenguaje han estado con nosotros durante mucho tiempo, todas las implementaciones de JavaScript las admiten, pero no formaron parte de la especificación hasta ECMAScript 5th Edition :
La
debugger
declaraciónDescrito en: § 12.15 La declaración del depurador
Esta declaración le permite poner puntos de interrupción mediante programación en su código simplemente por:
Si un depurador está presente o activo, hará que se rompa inmediatamente, justo en esa línea.
De lo contrario, si el depurador no está presente o activo, esta declaración no tiene ningún efecto observable.
Literales de cadena multilínea
Descrito en: § 7.8.4 Literales de cadena
\
Debe tener cuidado porque el carácter al lado del debe ser un terminador de línea, si tiene un espacio después del,\
por ejemplo, el código se verá exactamente igual, pero generará unSyntaxError
.fuente
JavaScript no tiene alcance de bloque (pero tiene cierre, así que vamos a llamarlo incluso?).
fuente
Puede acceder a las propiedades del objeto en
[]
lugar de.
Esto le permite buscar una propiedad que coincida con una variable.
También puede usar esto para obtener / establecer propiedades de objeto cuyo nombre no sea un identificador legal.
Algunas personas no saben esto y terminan usando eval () como este, lo cual es una muy mala idea :
Esto es más difícil de leer, más difícil de encontrar errores (no puede usar jslint), más lento de ejecutar y puede conducir a exploits XSS.
fuente
foo.bar
, De acuerdo con la especificación de todos modos, se comporta exactamente igualfoo["bar"]
. También tenga en cuenta que todo es una propiedad de cadena. incluso cuando hace acceso a la matrizarray[4]
, el 4 se convierte en una cadena (de nuevo, al menos según la especificación ECMAScript v3)Si buscas en Google una referencia decente de JavaScript sobre un tema determinado, incluye la palabra clave "mdc" en tu consulta y tus primeros resultados serán del Centro de desarrolladores de Mozilla. No llevo ninguna referencia fuera de línea o libros conmigo. Siempre uso el truco de palabras clave "mdc" para llegar directamente a lo que estoy buscando. Por ejemplo:
Google: javascript array sort mdc
(en la mayoría de los casos, puede omitir "javascript")
Actualización: Mozilla Developer Center ha cambiado su nombre a Mozilla Developer Network . El truco de la palabra clave "mdc" aún funciona, pero pronto tendremos que comenzar a usar "mdn" en su lugar .
fuente
Tal vez un poco obvio para algunos ...
Instale Firebug y use console.log ("hola"). Mucho mejor que usar la alerta aleatoria (); que recuerdo haber hecho mucho hace unos años.
fuente
Métodos privados
Un objeto puede tener métodos privados.
fuente
También mencionado en Crockford "Javascript: The Good Parts":
parseInt()
es peligroso. Si le pasa una cadena sin informarle de la base adecuada, puede devolver números inesperados. Por ejemplo,parseInt('010')
devuelve 8, no 10. Pasar una base a parseInt hace que funcione correctamente:fuente
Math.floor
oNumber
?10 === Math.floor("010"); 10 === Number("010");
flotadores:42 === Math.floor("42.69"); 42.69 === Number("42.69");
parseInt
función inofensiva podría hacerse fácilmente para hacer algo no tan inofensivo.__parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }
Las funciones son objetos y, por lo tanto, pueden tener propiedades.
fuente
Tendría que decir funciones autoejecutables.
Debido a que Javascript no tiene un alcance de bloque , puede usar una función de ejecución automática si desea definir variables locales:
Aquí,
myvar
no interfiere con el alcance global ni lo contamina, y desaparece cuando finaliza la función.fuente
.js
archivos en una función de ejecución automática anónima y adjunto todo lo que quiera accesible globalmente dentro delwindow
objeto. Previene la contaminación global del espacio de nombres.Sepa cuántos parámetros espera una función
Sepa cuántos parámetros recibe la función
fuente
function.length
.Aquí hay algunas cosas interesantes:
NaN
con cualquier cosa (inclusoNaN
) siempre es falso, eso incluye==
,<
y>
.NaN
Significa No es un número, pero si pregunta por el tipo, en realidad devuelve un número.Array.sort
puede tomar una función de comparación y es llamado por un controlador de tipo rápido (depende de la implementación).$0
,$1
,$2
los miembros de una expresión regular.null
Es diferente a todo lo demás. No es un objeto, un booleano, un número, una cadena, niundefined
. Es un poco como un "alternativo"undefined
. (Nota:typeof null == "object"
)this
produce el objeto [Global] que de otro modo no se podría nombrar.var
, en lugar de depender simplemente de la declaración automática de la variable, le da al tiempo de ejecución una oportunidad real de optimizar el acceso a esa variablewith
construcción destruirá tales optimizacionesbreak
. Los bucles se pueden etiquetar y usar como objetivo decontinue
.undefined
. (depende de la implementación)if (new Boolean(false)) {...}
ejecutará el{...}
bloque[actualizado un poco en respuesta a buenos comentarios; por favor vea los comentarios]
fuente
typeof null
devuelve "objeto".undefined
, pero ese es solo el valor predeterminado que obtiene cuando busca un índice que no existe. Si marcó un [2000], eso también seríaundefined
, pero eso no significa que todavía le haya asignado memoria. En IE8, algunas matrices son densas y otras son escasas, dependiendo de cómo se sintió el motor JScript en ese momento. Lea más aquí: blogs.msdn.com/jscript/archive/2008/04/08/…Sé que llego tarde a la fiesta, pero no puedo creer
+
que la utilidad del operador no se haya mencionado más allá de "convertir algo a un número". ¿Tal vez así de escondida está una característica?Por supuesto, puede hacer todo esto usando en su
Number()
lugar, ¡pero el+
operador es mucho más bonito!También puede definir un valor numérico de retorno para un objeto anulando el
valueOf()
método del prototipo . Cualquier conversión de número realizada en ese objeto no dará como resultadoNaN
, pero el valor de retorno delvalueOf()
método:fuente
0xFF
, etc., no es necesario+"0xFF"
.0xFF
, de la misma manera que puedes escribir en1
lugar de+true
. Estoy sugiriendo que puede usarlo+("0x"+somevar)
como una alternativaparseInt(somevar, 16)
, si lo desea." Métodos de extensión en JavaScript " a través de la propiedad prototipo.
Esto agregará un
contains
método a todos losArray
objetos. Puedes llamar a este método usando esta sintaxisfuente
Para eliminar correctamente una propiedad de un objeto, debe eliminarla en lugar de establecerla como indefinida :
La propiedad prop2 seguirá siendo parte de la iteración. Si desea deshacerse por completo de prop2 , debe hacer lo siguiente:
La propiedad prop2 ya no aparecerá cuando esté recorriendo las propiedades.
fuente
with
.Raramente se usa, y francamente, rara vez es útil ... Pero, en circunstancias limitadas, tiene sus usos.
Por ejemplo: los literales de objetos son bastante útiles para configurar rápidamente propiedades en un nuevo objeto. Pero, ¿qué sucede si necesita cambiar la mitad de las propiedades de un objeto existente?
Alan Storm señala que esto puede ser algo peligroso: si el objeto utilizado como contexto no tiene una de las propiedades asignadas, se resolverá en el ámbito externo, posiblemente creando o sobrescribiendo una variable global. Esto es especialmente peligroso si está acostumbrado a escribir código para trabajar con objetos donde las propiedades con valores predeterminados o vacíos se dejan sin definir:
Por lo tanto, probablemente sea una buena idea evitar el uso de la
with
declaración para dicha asignación.Ver también: ¿Existen usos legítimos para la declaración "con" de JavaScript?
fuente
Se pueden invocar métodos (o funciones) en objetos que no son del tipo con el que fueron diseñados para trabajar. Es genial llamar a métodos nativos (rápidos) en objetos personalizados.
Este código falla porque
listNodes
no es unArray
Este código funciona porque
listNodes
define suficientes propiedades de tipo matriz (longitud, operador []) para ser utilizadas porsort()
.fuente
La herencia de prototipos (popularizada por Douglas Crockford) revoluciona por completo su forma de pensar acerca de muchas cosas en Javascript.
Es un asesino! Lástima cómo casi nadie lo usa.
Le permite "engendrar" nuevas instancias de cualquier objeto, extenderlas, mientras mantiene un enlace de herencia (en vivo) prototípico a sus otras propiedades. Ejemplo:
fuente
Algunos llamarían a esto una cuestión de gustos, pero:
El operador trinario se puede encadenar para actuar como el esquema (cond ...):
Se puede escribir como...
Esto es muy "funcional", ya que ramifica su código sin efectos secundarios. Entonces en lugar de:
Puedes escribir:
Funciona bien con la recursividad, también :)
fuente
Los números también son objetos. Entonces puedes hacer cosas geniales como:
fuente
times
no es eficiente:Math.floor
se llama cada vez en lugar de solo una vez.¿Qué hay de los cierres en JavaScript (similar a los métodos anónimos en C # v2.0 +)? Puede crear una función que cree una función o "expresión".
Ejemplo de cierres :
fuente
También puede extender (heredar) clases y anular propiedades / métodos utilizando el prototipo de cadena cuchara aludida.
En el siguiente ejemplo creamos una clase Pet y definimos algunas propiedades. También anulamos el método .toString () heredado de Object.
Después de esto, creamos una clase Dog que extiende Pet y anula el método .toString () cambiando nuevamente su comportamiento (polimorfismo). Además, agregamos algunas otras propiedades a la clase secundaria.
Después de esto, verificamos la cadena de herencia para mostrar que Dog todavía es de tipo Dog, de tipo Pet y de tipo Object.
Ambas respuestas a esta pregunta fueron códigos modificados de un gran artículo de MSDN de Ray Djajadinata.
fuente
Puede detectar excepciones según su tipo. Citado de MDC :
NOTA: Las cláusulas de captura condicional son una extensión de Netscape (y, por lo tanto, Mozilla / Firefox) que no forma parte de la especificación ECMAScript y, por lo tanto, no se puede confiar, excepto en navegadores particulares.
fuente
La parte superior de mi cabeza...
Las funciones
argumentos.callee se refiere a la función que aloja la variable "argumentos", por lo que puede usarse para recurrir funciones anónimas:
Eso es útil si quieres hacer algo como esto:
Objetos
Una cosa interesante sobre los miembros del objeto: pueden tener cualquier cadena como sus nombres:
Instrumentos de cuerda
String.split puede tomar expresiones regulares como parámetros:
String.replace puede tomar una expresión regular como parámetro de búsqueda y una función como parámetro de reemplazo:
fuente
arguments.callee
está en desuso y arrojará una excepción en ECMAScript 5.Puede usar objetos en lugar de interruptores la mayor parte del tiempo.
Actualización: si le preocupa que los casos que evalúan por adelantado sean ineficientes (¿por qué le preocupa la eficiencia desde el principio en el diseño del programa?), Puede hacer algo como esto:
Esto es más oneroso de escribir (o leer) que un interruptor o un objeto, pero conserva los beneficios de usar un objeto en lugar de un interruptor, detallado en la sección de comentarios a continuación. Este estilo también hace que sea más sencillo convertir esto en una "clase" adecuada una vez que crece lo suficiente.
update2: con extensiones de sintaxis propuestas para ES.next, esto se convierte en
fuente
var arr = []; typeof arr; // object
Asegúrese de utilizar el método hasOwnProperty al recorrer las propiedades de un objeto:
Esto se hace para que solo acceda a las propiedades directas de unObjeto y no use las propiedades que se encuentran en la cadena del prototipo.
fuente
Variables privadas con una interfaz pública
Utiliza un pequeño truco con una definición de función de llamada automática. Todo lo que se devuelve dentro del objeto está disponible en la interfaz pública, mientras que todo lo demás es privado.
fuente