Todo lo que un desarrollador no puede desconocer de javascript

javascriptpicmd2

Este es un compilado que hago en base a algunos libros que lei, experiencias y webs sobre javascript, y considero que todo desarrollador deberia conocer

Antes de comenzar les recomiendo si quieren profundizar en el tema aún más, lean Javascript the Goods Parts, libro escrito por uno de los maestros de javascript Douglas Crockford,
Y también Javascript Patterns un libro de Stoyan Stefanov que apunta a los niveles intermedios y avanzados de javascript y que francamente lo ubico entre los mejores libros que he leido.

Bien la idea de este compilado es contarles un poco sobre funciones y cuestiones basicas y avanzadas de javascript.

Para comenzar me gustaría contar que javascript es un lenguaje funcional orientado a objetos con herencia de prototipos , esto que significa?

Los objetos y clases que conocemos de otros lenguajes como php no son representados de la misma manera, en javascript objetos heredan de otros objetos y no tenemos clases.
Javascript es un lenguaje que se formo en base a varios lenguajes, tomó la sintaxis de java, las expresiones regulares de perl, las funciones de Schema, y colaboró con el desarrollo propio de los prototipos.

Javascript es un lenguaje no tipado , si bien cada variable al asignarle un valor obtiene un tipo no hay que definir el tipo con previo aviso, también permite que las variables puedan pasar a contener valores de tipos diferentes a los originales , por lo que hay que tener mucho cuidado con eso.

Sobre variables globales en javascript

Cada vez que se define una varible sin estar contenida en una función esta toma como ámbito todo el proyecto en otras palabras se convierte en una variable global , algo que a los desarrolladores no les gusta para nada ya que es proclibe a generar problemas, toda variable depende de un contexto , si se crea dentro de una función su contexto será la función, si se crea dentro de un objeto dependerá del objeto y si se crea sin hacer referencia a nada es decir sin estar incluida en ningún lado , sobre el cuerpo de la página como ya dije será una variable global y dependerá del objeto window.

por ejem si creo la variable nombre

var nombre;

es lo mismo que hacer
this.nombre;

o también
window.nombre;

algo muy peligroso ya que en window también hay otras variables del sistema que son reservadas y uno las podría llegar a pisarlas sin querer, u obtener errores al hacerlo.

es por eso que los buenos desarrolladores crean una variable global a la que denominan namespace y dentro de esta variable o namespace incorporan todo su código.
por ejemplo

var NAMESPACE={};
NAMESPACE.nombre=’tutorial’;

de esta forma todo queda contenido dentro de NAMESPACE y nos aseguramos de que nada se nos escape por ahi.
Use NAMESPACE pero podria ser cualquier otra variable, y las mayusculas es solo por convención de variables globales.

Funciones en javascript

Hablando de funciones, estas no son lo que acostumbramos a ver en otros lenguajes tradicionales, las funciones son objetos y por lo tanto son asignables, es por eso que se pueden asignar funciones a variables, a las cuales se las denomina funciones anonimas. Toda creación de funciones se hace de esta manera aunque lo definamos de manera diferente, por ejem:
Cuando se crea una función dandole un nombre en realidad todo es un truco ya que internamente se crea una variable con el nombre de la función y le asigna la función adentro, algo bastante complicado de imaginar pero es así.

Todas las funciones tienen un link al prototipo Function que a su vez tiene un link al prototipo Object, es por eso que si le aplicamos el operador typeof a la función nos devuelve object y si extendemos el prototipo de Object al mismo tiempo extendemos el prototipo Function.

Respecto a los parametros de las funciones, javascript no genera un error si la cantidad de valores que se pasan no es la misma que la que se espera. En si lo que sucede es, si la función espera 3 parametros y se le pasan 4 valores, el último valor es descartado, si la función espera 3 y se le pasan solo 2, el último parametro de la función contendrá “undefined”.
Javascript no posee un sistema para establecer parametros por defecto , si el parametro no viene se llena con undefined y es todo, de ahi pueden surgir varias formas de solucionar el problema.
jQuery tiene un método extend que funciona muy bien, pero también podriamos preguntar “if (variable typeof indefined)” y completar con lo que queremos o también una forma muy elegante es

function (var1,var2){
var1 = var1 || ‘valor1′;
var2 = var2 || ‘valor2′;
}

De esta manera si el valor no viene el operador or (||) dará falso en su primera instancia devolviendo la segunda que dará true, las variables var1 y var2 se cargarian con los strings “valor1″ y “valor2″ respectivamente.
esta claro que este método es válido si lo que queremos asignar por defecto es algo que al evaluar da true, usando por ejem null no funcionaría, y si pasamos por parametros un valor falso , tomaría como que el parametro no existe, descartaría ese valor y usaria el valor por defecto.

Objetos en javascript

Existen los objetos en javascript y existe la herencia donde objetos heredan de otros objetos (lo veremos mas abajo), existe el foreach y existen los arrays estos últimos con estructura limitada.

Hay 3 formas de crear un objeto en javascript

1-Mediante literales, declaración directa

var objeto = new Objet();

ó también

var objeto ={} // objeto vacio
var objeto ={name:’lucas’,lastname:’forchino’}; //objeto con atributos

//objeto con métodos
var objeto ={
name:’lucas’,
lastname:’forchino’,
getName:function(){return this.name}
}

cuando el objeto se crea usando literales, posee un link al prototipo Object, de esta manera si extendemos a Object extendemos también a los objetos. Esto es: agrego un nuevo método a Object y todos los objetos pasan a tener ese método sin importar en que lugar del código fueron creados, con esto digo , creo un objeto 1 luego extiendo a Objecto con el método 2 luego el objeto 1 por más que fue creado con anterioridad pasa a contener el método 2.

2-Crear un objecto clonando usando un truco muy simple

Para clonar un objeto de otro objeto se usa truco es muy simple , se crea una función vacía, a esta se le extiende el prototipo asignandole el objeto a clonar, de esta manera obtenemos una función constructora con la estructura del objeto, posteriormente se crea el nuevo objeto usando new.

var objeto ={name:’lucas’,lastname:’forchino’}; //objeto con atributos a clonar

creamos la funcion vacia

var F=function(){} ;

copiamos el objeto dentro del prototipo de la función
F.prototype = objeto;

obtenemos el objeto nuevo
objeto2 = new F();

una vez aprendida esta técnica se puede meter dentro de una función para hacerlo mas rápido y despreocuparse de su implementacion.
En si lo que se hace es usar el método de creación 3 (a continuación) adaptado a objetos que no tienen constructor.

3- Si contiene constructor , invocarlo mediante el operador new

Una variable que contiene una función es utilizada como constructora de un nuevo objeto.
Estas variables por convención deben empezar con mayúscula y serian de la forma

var Objeto = function(){
this.name=’lucas’;
this.lastname=’forchino’;
}

Utilizando la función constructora genero un objeto nuevo.

var objeto2 = new Objeto;

Otra forma de crear un objeto de deriva de las formas anteriores es retornando el objeto por medio de una función, en si la creación se produce dentro de la función y se asigna su resultado a una variable que contendrá el objeto. Este método es muy interesante ya que, debido al closure, permite hacer cosas como mantener atributos privados dentro de un objeto.

var objectFactory=function(){
// variable solo accesible por la funcion siguiente debido a closure
var variable_privada=’31′;

// función u objeto que se retorna, que tiene acceso a la variable anterior
return function(){
this.name =”lucas”;
this.apellido=”forchino”;
this.getEdad=function(){
return variable_privada;
}

}

}

luego para obtener un objeto nuevo hacemos

var objeto2= objectFactory();


Herencia en javascript:

Hay varias formas de crear herencia en javascript, solo voy mostrar las dos mas simples y comunes.

1-Sobrecargando directamente un objeto

Algo muy simple de pensar si tengo dos objetos iguales creados de la misma forma, incorporando métodos a uno estoy extendiendo el objeto original.
tenemos

var Objeto = function(){
this.name=’lucas’;
this.lastname=’forchino’;
}

var objeto1= new Objeto;
var objeto2= new Objeto;

extiendo el objeto 2 añadiendo un atributo y un método
objeto2.middleName=’francisco’;
objeto2.getMiddleName= funcion(){
return this.middleName;
}

de esta forma el objeto1 se mantiene su estructura original mientras que el objeto2 fue extendido de Objeto agregando un atributo y un método.

2-Añadir el objeto padre en el prototipo del objeto hijo

// creo el constructor del objeto padre
var Padre=function(){
this.name=’jose’;
this.apellido=’forchino’;
}

// constructor del objeto hijo
var Hijo=function(){
this.name=’lucas’;
}

// heredo del padre añadiendo el objeto padre al prototipo del hijo usando new ! muy importante de otra manera asignariamos la función al prototipo y no el objeto
Hijo.prototype=new Padre();

// creo un objeto hijo
var obj= new Hijo;

//el objeto hijo contiene la estructura del padre y del hijo, los atributos o metodos que prevalecen son los del
// hijo por sobrecargar al padre

document.writeln(obj.name); // lucas
document.writeln(obj.apellido); //forchino

// si cambio el prototipo de la función padre
Padre.prototype.edad=56;

// todos lo hijos cambian su prototypo , si imporatar si ya fueron creados, todos pasan a leer el atributo añadido.
document.writeln(obj.edad); // 56

Scope de variables en javascript.

Este es uno de los temas más simples y mas complejos a la vez un error podria hacer que nuestro programa tenga comportamientos extraños muy dificiles de debuggear.
Hay 4 tipos de scope que puede obtener el metodo this en javascript

1- Dentro de la función u objeto donde se hace referencia a la misma función u objeto

Todos los métodos de un objeto cuando invocan “this” hacen referencia a su mismo objeto, esto es

Objeto={
name:’lucas’.
getName:function(name){
return this.name;
}
}

El return devolverá el valor guardado en name del objeto ya que “this” se refiere al objeto mismo, para complicar mas las cosas pase por parametro un valor name, este valor name es una variable local que no influye en el valor devuelto y no tiene nada que ver con el valor name del objeto, de esta manera podemos trabajar con ambas variables name sin problemas haciendo referncia a una u otra con o sin “this”.

2- Fuera del objeto donde se hace referencia al entorno global

Cualquier funcion que no esta dentro de un objeto , es decir no es un método de algún objeto , “this” hara referencia a window, esto si uno se lo imagina como funciones generales podría llegar a pensar que no hay problemas ya que si tenemos una función suelta por ahi podría ser válido que “this” llame a lo que tiene inmediatamente arriba que es el objeto window del cual depende.
El problema surge cuando tenemos una función dentro de otra función y es ahi donde uno espera que las funciones internas hagan referencia con “this” a las externas cuando en realidad por un error del lenguage todas las funciones apuntan con this al ámbito global.

es por esto que si tenemos

var a= function(){
this.contenido=”a”;
this.b = function(){
this.contenido=”b”;
}

}

var contenido=”;
a();

// contenido vale “a”

b(); // puedo llamar a b mágicamente

// contenido vale “b”

lo que sucede es que a modifica la variable global porque “this” hace referencia a ese ámbito, luego crea un función que se llama b sobre el entorno global porque la misma situación, si ejecutamos b() también modificará la variable global porque al no ser un método de un objeto también modifica el ámbito global.

3- Dentro de un constructor donde se referencia a un nuevo objeto

Dentro del constructor o función constructora, “this” hace referencia al objeto que se esta creando. La creación de un objeto usando un constructor funciona de la siguiente manera hacemos new sobre una variable que contiene una función y esto internamente crea objeto vacio que se pasa como ámbito u objeto “this” a la función constructora, la función cuando trabaja sobre métodos u atributos usando “this” esta trabajando sobre ese nuevo objeto creado, luego simplemente lo retorna por mas que nuestra función no tenga un return.

si nuestra función constructora tuviera un return, la función trabajaría sobre el objeto nuevo pero devolvería lo que retornamos con return.

Hay que tener en cuenta que en estos casos solo se pueden retornar objetos, como una función es un objeto , también es valido retornar una función, si lo que se retorna no es un objeto la función retornara el objeto inicialmente creado dejando de lado el valor puesto en return.
Esto es:

a- No tengo Return

Como resultado obtengo un nuevo objeto que fue previamente pasado a la función y al cual esta hizo referencia con “this”

var Objeto = function(){
this.name=’lucas’;
}
var ob= new Objeto(); // ob = {name:’lucas’}

b- Retorno un string

Obtengo el mismo resultado que el caso 1 , ya que el return no es un objeto

var Objeto = function(){
this.name=’lucas’;
}
var ob= new Objeto(); // ob = {name:’lucas’}

c- Retorno un Objeto

Obtengo el objeto retornado, en este caso es un objeto vacio

var Objeto = function(){
this.name=’lucas’;
return {};
}
var ob= new Objeto();// ob ={}

d- Retorno una función

Obtengo una función puesto que como ya dijimos las funciones son objetos también.

var Objeto = function(){
this.name=’lucas’;
return function(){};
}
ob= new Objeto();// ob =function

4- Usando el método apply forzamos el scope a que tome un valor definido

El método apply toma dos argumentos, el primero es el ámbito y el segundo son parametros, de esta forma podemos ejecutar una función diciendole cual es el ámbito que queremos que tome y cual son los parametros que tomará.

var a = function (params){}

a.apply(this,params);

en este caso la función a correrá con el ámbito “this” que se paso por parametro y hacen referencia al ámbito en el que se encuentra a, también podriamos reemplazar “this” con un objeto function o lo que sea que se quiera como ámbito, los parametros en este caso representados por params deben ser un array con valores que serán los que recibira la función “a”

Expresiones regulares en javascript

Una de las grandes cualidades de javascript es la incorporacion de expresiones regulares, uno de los grandes problemas al mismo tiempo es la legibilidad de ellas. Es muy dificil poder seguirlas y cuando son extensas se hace mucho mas dificil, la imposibilidad de insertar espacios en blancos o incluso poder separarlas hace que se conviertan en cadenas de una sola linea ilegibles, muy dificil de mantener y crear, lo positivo es que permiten validar códigos complejos a los cuales se les quiere ocultar la estructura de como estan formados.

Deje un Comentario

*