Ocho cosas que
debes saber de
JavaScript
por
David Avellaneda @davsket
sobre mí
Soy front­end developer y co­fundador de Monoku y
Monomi y también soy co­organizador de BogotaJS.
1
coerción
Def.
Es forzar el cambio de un tipo a otro, por ejemplo: cambiar
de un número a una cadena de texto.
Temor
Algunos temen el uso de la coerción y la tildan como mala
práctica, e incluso como peligrosa.
Pero
La coerción se encuentra naturalmente en JavaScript.
De hecho es natural en muchos lenguajes.
Muchas veces pasa
implícitamente
Cuando verificas si una
variable existe
if( variable ){}
// JavaScript lo coerce a booleano
// es equivalente a:
if( Boolean(variable) ){}
// o...
if( !!variable ){}
Cuando accedes una
propiedad sin string
myObj[ 3 ];
// JavaScript lo coerce a string
myObj[ '3' ]
// Yep, arreglos tambien aplican
[ 1, 2, 3 ][ '2' ] // 3
Cuando usas isNaN
15.1.2.4 isNaN (number)  
Returns true if the argument coerces to NaN,
and otherwise returns false.
­ Annotated ECMAScript 5 ­
...isNaN
isNaN( '3' )
// +'3' -> 3
// entonces
> false
isNaN( '3px' )
// +'3px' -> NaN
> true
...isNaN (2)
isNaN( '' )
// +'' -> 0
> false
isNaN( {} )
// +{} -> NaN
> true
...isNaN!! (3)
isNaN( { valueOf: function(){
return 2 }} )
//+{ valueOf: function(){ return
2 }} -> 2
> false
isNaN( { valueOf: function(){
return '' }} )
// +{ valueOf: function(){ return
0 }} -> +'' -> 0
> false
o explícito...
Cuando concatenas...
var edad = 20;
console.log( "Tu edad es: " +
edad );
// JavaScript coerce edad<number>
a string
console.log( "Tu edad es: " +
"20" )
Cuando usas un contructor
de tipo core como función,
es decir, sin new
Boolean( 19 ) // true
String( 19 ) // '19'
Number( '19' ) // 19
Number( true ) // 1
ej: coerción de fechas
var date = new Date()
date.getTime() // 1367795189000
date.valueOf() // 1367795189000
+ date // 1367795189000
date.toString() // "Sun May 05
2013 ..."
date + '' // "Sun May 05 2013
..."
ej: coerción de strings
var text = '123'
parseInt( text ) // 123
Number( text ) // 123
+ text // 123
Coerción de strings (2)
var text = '34.5%'
Number( text ) // NaN
+ text // NaN
parseInt( text ) // 34 <- yeah!
parseFloat( text ) // 34.5 <-
yeeeah!
buena práctica # 1
Usar parseInty parseFloatpara la conversión
numérica.
2
operadores bit a bit
WARNING!
El uso de operadores bit a bit fuera de operaciones
booleanas o binarias se presta para errores.
String.indexOf ( less Evil )
~str.indexOf(',')
~-1 // 0 -> false
~0 // 1
~1 // 2
~2 // 3
~n // n+1
~21474836479 // 0 -> false ->
fail!, común?
Mejores soluciones..
str.indexOf(',') + 1
str.indexOf(',') > -1 // más
legible
str.indexOf(',') >= 0 // más
legible
Redondeo o Floor ( so Evil )
// NOT
~~10.2 // 10
// SHIFT
10.2 >>> 0 // 10
// SHIFT (Sign-propagating)
-10.2 >> 0 // -10
// XOR
10.2 ^ 0 // 10
// OR
10.2 | 0 // 10
Pero
Las operaciones binarias no tienen encuenta signo y se
encuentran limitadas a 4 bytes (32 bits) y los números
pueden ir hasta 8 bytes o más.
var n = 2147483647
console.log( n.toString( 2 ) )
> 1111111111111111111111111111111
//
01111111111111111111111111111111
ERROR!
// NOT
~~2147483647 // -2147483648
// SHIFT
8589934591 >>> 0 // 4294967295
-10.2 >>> 0 // 4294967286
// SHIFT (Sign-propagating)
2147483648 >> 0 // -2147483648
buena práctica # 2
Usar Math.round, Math.floory Math.ceilpara
redondear los números.
3
hoisting
hoist 
To raise or haul up with or as if with the help of a
mechanical apparatus.
­ The Free Dictionary ­
Def.
Javascript siempre lleva la definición de variables (
cualquiera ) al comienzo de la función ( realmente scope ).
ejemplo
var i = 1,
j = 2
function hoisting(){
console.log( i )
console.log( j )
var i = 3
console.log( i )
}
hoisting()
lo que realmente imprime
var i = 1,
j = 2
function hoisting(){
console.log( i ) // undefined
console.log( j ) // 2
var i = 3
console.log( i ) // 3
}
hoisting()
lo que pasa
var i = 1,
j = 2
function hoisting(){
var i
console.log( i )
console.log( j )
i = 3
console.log( i )
}
hoisting()
ejemplo con funciones
console.log( func1() )
console.log( func2() )
function func1(){ return 1 }
var func2 = function(){ return 2
}
ejemplo con funciones (2)
console.log( func1() )
console.log( func2() )
function func1(){return 1} //
declaración
var func2 = function(){return 2}
// expresión
ejemplo con funciones (3)
console.log( func1() ) // 1
console.log( func2() ) //
TypeError
function func1(){ return 1 }
var func2 = function(){ return 2
}
lo que pasa
Las definiciones son movidas al principio:
var func2;
function func1(){ return 1 }
console.log( func1() )
console.log( func2() )
func2 = function(){ return 2 }
ejemplo feo
function foo(){
function bar() {
return 3;
}
return bar();
function bar() {
return 8;
}
}
alert(foo());
Function Declarations vs. Function Expressions by Angus Croll
buena práctica # 3
Definir todas las variables lo antes posible en la función.
4
scope
Def.
Se refiere al entorno de definición de las variables,
usalmente una función tiene acceso a los scopes
superiores, pero no a inferiores.
ejemplo scope
var a = 3,
b = 4;
function func(){
var a = 4;
return a + b;
}
func(); // 8;
ejemplo scope (2)
var a = 3,
b = 4;
function func(){
var a = 4;
function funcInterna(){
var b = 0;
a = 0;
}
funcInterna();
return a + b;
}
func(); // 4
buena práctica # 4
Siempre definir las variables de la función usando var.
buena práctica # 5
Usar la expresión "use strict";para evitar el cambio
de variables externas al scope.
5
bind, call, apply
bind, call, apply
Todas son funciones de las funciones
bind( this )
Retorna una nueva función done el thises suplantado.
ejemplo bind
var obj = {
a: 3,
f: function(){
return this.a;
}
},
a = 5;
obj.f() // 3
obj.f.bind( this )() // 5
obj.f() // 3
call( this, [param1, [ param2,
...]])
Ejecuta una función definiendo el this para la ejecución
y recibe los parámetros.
ejemplo call
var obj = {
r: 3,
f: function( p ){
return p * this.r;
}
},
obj2 = {
r: 5
};
obj.f( 2 ) // 6
obj.f.call( obj2, 2 ) // 10
apply( this, params[])
Ejecuta una función definiendo el thisde una función y
sus parámetros como un arreglo.
ejemplo apply
var obj = {
r: 3,
f: function( p, q ){
return p * this.r + q;
}
},
obj2 = {
r: 5
};
obj.f( 2, 2 ) // 8
obj.f.call( obj2, [2, 2] ) // 12
pero apply es más cool que
eso!
ejemplo cool de apply
var arr = [23, 45, 17, 9]
Math.max.apply(null, arr) // 45
Math.min.apply(null, arr) // 9
6
prototype
Def.
Es una cadena de herencia de funcionalidades y
propiedades.
Ejemplo
En el prototipo del Array existen diferentes
funcionalidades dentro de un mismo tipo.
ventaja
Se puede extender en tiempo de ejecución a todas las
variables de un mismo tipo.
extensión
var arr = []
console.log( arr.ola )
> undefined
Array.prototype.ola = "k ase"
console.log( arr.ola )
> "k ase"
extensión cool
var bbc = "BogotáBeerCompany"
String.prototype.rocks =
function(){
return "✪ " + this + " Rocks! ✪"
}
bbc.rocks()
> ✪ BogotáBeerCompany Rocks! ✪
Warning... ?
Colisión de definiciones, es como jugar a modificar un
name­space.
extensión
Object.defineProperty(
String.prototype, 'slugify', {
value: function slugify() { ...
},
configurable: true,
enumerable: false,
writeable: true
});
7
JavaScript es UCS-
2
hämmästyttävä невероватно дзіўны úžasný удивительный
놀랄만한 า ศจรร ‫ַמייזינג‬‫א‬ tuyệt vời ఆశ ర ం அ தமான
驚人 ‫ا‬ ເຮດໃຫປະລາດ საოცარი զարմանալի
আ যজনক
http://mothereff.in/js­variables
Muchos caracteres
var π = Math.PI,
ಠ_ಠ = eval,
λ = function() {}
Pero en resumen...
Espagnol
var año = 2013,
español = true,
cuánto = 12000
function cálculoExtraño(){
return año * cuánto
}
if( español ){
cálculoExtraño()
}
> 24156000 //Oh si!
8
el punto y coma es
opcional
Sip, puede provocar
errores...
Pero si los conoces los puedes evitar, incluso pasan con el
uso de punto y coma...
return statement
Si return recibe un cambio de línea, retorna undefined.
function fn (){
return
{
edad: 20
};
}
fn() // undefined
return statement solved
function fn (){
return {
edad: 20
}
}
fn() // { edad: 20 }
paréntesis, el "enemigo"
var a = 1, b = 2, c = 3
(a * b)
> Number is not a function
paréntesis, lo que interpreta
var a = 1, b = 2, c = 3(a * b)
paréntesis, solución
var a = 1, b = 2, c = 3;
(a * b)
pero pasaba antes del boom
(function(){ return 2 }())
(function(){ return 3 }())
//Number is not a function
pero pasaba antes del boom
(function(){ return 2 }());
(function(){ return 3 }())
sí, los paréntesis son
delicados
y requieren punto y coma para evitar este tipo de errores.
FIN
David Avellaneda  
@davsket
en Github: davsket/ocho­cosas  
 
PD: originalmente incluía:  
1) Funciones ternarias y  
2) Math, parseInt y globales.

Ocho cosas que debes saber de JavaScript