Funciones en JavaScript

¿Qué es una función?

Es una porción de código que se ejecuta cuando algo la invoca. Empecemos viendo como se crean.

Creación y declaración de funciones

function double(num){ 
    return num*2; 
}
eso crea una variable "double" con el código de la función
//tambien se pueden crear funciones como expresión
var double = function(){ 
    return num * 2; 
} 
esto es un poco diferente a lo anterior, ya que se crea una variable double y se le asigna una función anónima, es anónima porque no tiene nombre.

Una de las principales diferencias entre estas dos formas de crear funciones es que la primera esta disponible inmediatamente, en cambio la segunda solo esta disponible después de ser declarada.

 
console.log(typeof triple); // function
console.log(typeof double); // undefined

function triple( num ){ 
    return num * 3 
};

var double = function( num ){ 
    return num * 2; 
};
console.log(typeof double); // function
Esto es una particularidad de JavaScript al ser un lenguaje interpretado, se llama Hoisting y también pasa con las variables y todas las declaraciones, pero aquí vengo a hablar de funciones.

Invocar funciones

Existen dos formas de invocar una función, la mas común es con un par de paréntesis “()” después del nombre o variable que la contenga.

 

double(4) // 4

triple(4) // 12

Ya sabemos que se pueden guardar funciones en variables, pero también las podemos guardar en arrays o en objetos.

 

//creamos un array con una funcion dentro.
var un_array = [ function(num){ return num * 2; } ] 

//al array anterior le agregamos otra funcion.
un_array.push( function(num){ return num * 3; } ) 

//asignamos otra variable anonima en el indice 2 del array
un_array[2] = function(num){ return num * 4 }

//y las ejecutamos
un_array[0](3) // 6 
un_array[1](3) // 9
un_array[2](3) // 12

¿Podemos crear una función sin darle un nombre y sin asignarla a una variable?

Si intentamos hacer esto “function(){}” obtendremos un error (variando según el entorno en el que se ejecute)

pero cuando creamos una función y la asignamos a un variable, decimos que esa función es una expresión, y para que nos entendamos y sin alargar esto demasiado, en resumen una expresión es todo lo que se evalúa y devuelve un valor.

 

// como una suma
3 + 2 // 5

// o una comparación lógica 
2 == "tres" // false

// y estas intuitivamente se pueden agrupar con paréntesis 
(2 + 4) / 2 // 3

y aquí esta la clave, usar junto a la función operadores matemáticos, compradores lógicos o cualquier cosa que obligue a JavaScript evaluar esa función.

 
0-function(){ } // NaN
1*function(){ } // NaN
+function(){ }  // NaN
true==function(){ } // false
!function(){ }  // false
(function(){}) // [Function]

Ya no obtenemos un error, pero tampoco podemos hacer algo útil con todo eso, pero si nos fijamos en el ultimo ejemplo el interprete nos devuelve [Function], eso es una función anónima, y como no tiene nombre y no la asignamos a una variable no podemos invocarla luego.

pero si podemos invocarla inmediatamente, de igual forma como invocamos a las otras funciones, agregando un par de paréntesis al final.

 
(function(){}) ()

y de esta forma es como se crean las ya famosas funciones anónimas auto-ejecutables, vamos a ver su utilidad.

Funciones anónimas auto-ejecutables

Todo lo que se declara dentro de una función es accesible solo dentro de esa función, de igual forma los parámetros que recibe al ser invocada, por lo tanto podemos usar una función anónima auto-ejecutable para aislar nuestro código.

 
for (var numero = 0; numero < 5; numero++) {
	var soy_asincrona = function(){
		console.log( numero );
	};
	setTimeout( soy_asincrona, 1000 );
}
dentro de un ciclo for creamos una función, que mostrara el valor de "numero" luego de un segundo.
Al ejecutarlo nos damos cuenta que se imprime 5 veces el numero 5, y no del 0 al 4 como se podría esperar.

Lo anterior sucede porque al momento de ejecutarse las funciones “soy_asincrona” el ciclo for ya termino de ejecutarse por o que el valor de la variable “numero” es 5.
y esto lo podemos solucionar precisamente encapsulando las variables que no queremos que cambien.

 
for (var numero = 0; numero < 5; numero++) {
	(function(numero){
		var soy_asincrona = function(){
			console.log( numero );
		};
		setTimeout( soy_asincrona, 1000 );
	})(numero)
}
usamos 2 variables 'numero' y 'asincrona'

También nos podemos encontrar con este tipo de situaciones cuando recorremos elementos del DOM y le asignamos eventos utilizando el indice que usamos para recorrerlos.
Por supuesto esta no es la única forma de resolver este problema.

for (var numero = 0; numero < 5; numero++) {
	var funct1 = function(numero){
		var soy_asincrona = function(){
			console.log( numero );
		};
		setTimeout( soy_asincrona, 1000 );
	}
	funct1(numero);
}
usamos 3 variables, numero, func1 y soy_asincrona

Pero todavía podemos abusar un poco mas de las funciones anónimas, una función puede ser pasada por parámetro a otra función, por lo que podemos enviarla directamente.

for (var numero = 0; numero < 5; numero++) {
	
	(function(numero){
		
		setTimeout( function(){
			console.log( numero );
		}, 1000 );
		
	})(numero)	
}
en este caso solo usamos 1 variable, numero

Pongámonos un poco mas exigentes, e intentemos que la función “setTimeout” se ejecute solo un nivel dentro del for, y NO anidado dentro de otra función.
para eso vamos a crear una función que retorne otra función.

for (var numero = 0; numero < 5; numero++) {
	
	var doit = (function(numero){
		
		return function(){
			console.log( numero );
		}
		
	})(numero)
	
	setTimeout( doit, 1000 );
	
}
enviando una función anónima dentro de una variable
for (var numero = 0; numero < 5; numero++) {
	
	setTimeout( (function(numero){
		
		return function(){
			console.log( numero );
		}
		
	})(numero), 1000 );
	
}
enviamos directamente una función anónima auto ejecutable

Funciones y new

Al principio mencione que hay dos formas de invocar una función pero solo he usado una, la otra forma es anteponiendo la palabra “new”

var greet = function( num ){
	console.log( "hello" );
}
new greet;
vemos como se ejecuta la función, y como curiosamente obtenemos algo mas en la consola


hemos creado un objeto del tipo greet :’)

y hasta aquí lo dejo, ya veremos objetos con la atención que merecen mas adelante.

Leave a Comment

Su dirección de correo no se hará público. Los campos requeridos están marcados *