Beruflich Dokumente
Kultur Dokumente
(buenas) prácticas
1. Funciones 3. Asincronismo
a. Closures a. Hosting environment
b. Module pattern b. Event loop
c. AMD y RequireJS c. Callbacks
2. Objetos d. Promises
a. Tipos e. Q
b. Herencia prototípica 4. Underscore.JS
c. this
d. new
JS
Funciones
léxico dinámico
FUNCIONES
Scopes
léxico
FUNCIONES
Scopes
function() {
léxico }
function() {
function() {
función }
}
FUNCIONES
Expresiones y declaraciones
function hacerAlgo() { ... }
Y ahora?
Closures
Se producen en los lenguajes con funciones de primera clase.
función entorno
function sumarA(x) {
return function(y)
{
return x + y;
}
}
FUNCIONES
Closures
5 5 5 5 5
Closures
function(j){
setTimeout(function (){
console.log( j );
FUNCIONES
}, i*1000);
}
Closures
function() {
function() {
function() {
}
FUNCIONES
}
IIFE
IIFE
Immediately Invoked Function Expression
(function hacerAlgo() {
...
})();
closure
MODULE PATTERN
Module pattern
function () {
};
MODULE PATTERN
Module pattern
function () {
var metodoPrivado = function () { ...}
};
MODULE PATTERN
Module pattern
function () {
var metodoPrivado = function () { ...}
return {
metodoPublico: function() { ... }
}
};
MODULE PATTERN
Module pattern
return {
metodoPublico: function() { ... }
}
};
MODULE PATTERN
Múltiples instancias
var a = Modulo();
var b = Modulo();
MODULE PATTERN
var c = Modulo();
Múltiples instancias
var a = Modulo();
a.metodoPublico();
MODULE PATTERN
Module pattern
IIFE closure
MODULE PATTERN
Module pattern
(function () {
})();
MODULE PATTERN
Singleton
return {
metodoPublico: function() { ... }
}
})();
MODULE PATTERN
Modulo.metodoPublico();
Construyendo la API
retorno.metodoPublico = function() {
... }
MODULE PATTERN
return retorno;
})();
Revealing
return retorno;
})();
Augmentation
Modulo.otroMetodoPublico = function {
... }
return Modulo
MODULE PATTERN
})(Modulo || {});
Mixins
})(jQuery, _);
MODULE PATTERN
MODULE PATTERN
AMD
Asynchronous Module Definition
}
});
MODULE PATTERN
REQUIRE JS
Require JS
define(“modulo”, [“require”],
function (require) {
}
});
REQUIRE JS
Require JS
requirejs.config({
baseUrl: 'lib',
paths: {
app: '../app'
}
});
requirejs(['app/main']);
REQUIRE JS
Require JS
define(function (require) {
print(messages.getHello());
});
REQUIRE JS
{}
Objetos
var obj = { ... }
No todo es un objeto!
OBJETOS
Tipos primitivos
object
OBJETOS
Tipos primitivos
object
function
OBJETOS
Tipos primitivos
object
array function
str.length
primitive string
OBJETOS
Cohersion
str.length
str.charAt(3);
str.length
primitive string
object “String”
OBJETOS
Formas literales y construidas
Number number
Error
null
Propiedades
obj.identificador
obj[“identificador”]
obj[“Hola!”]
fn.apply(obj, {a:1,b:2,c:3}); // 1 2 3;
obj
OBJETOS
this
(explicit binding)
var fn = function(a,b,c) {
console.log([a,b,c].join(“ “));
return this;
}
fn.call(obj,1,2,3); // 1 2 3; obj
OBJETOS
this
(explicit binding)
var fn = function(a,b,c) {
console.log([a,b,c].join(“ “));
return this;
}
fn2 = fn.bind(obj,1,2);
fn(3); // 1 2 3; obj
OBJETOS
this
1. En el caso del operador new, refiere al objeto creado
(new binding)
2. Si es llamada utilizando call o apply, el objeto empleado
en el primer parametro de la llamada
(explicit binding)
3. Si es una invocación al método apuntado por una
propiedad de un objeto, this refiere al objeto
(implicit binding)
4. Por defecto, es el objeto global
(default binding)
OBJETOS
Herencia
Herencia clásica o tradicional
Herencia prototípica
obj.a; // 10
obj.c; // 30
Herencia prototípica
obj objPrototype
__proto__ __proto__
a 10 c 30
b 20 d 40
d 50 …
…
HERENCIA PROTOTÍPICA
b.calcular(30); // 60
c.calcular(40); // 80
Herencia prototípica
a
b
__proto__
__proto__
y 20
y 20
c
HERENCIA PROTOTÍPICA
__proto__
Object.prototype
y 30
__proto__ null
builtins
new
Calculadora
__proto__
Calculadora = function() { ... }
prototype
otros
HERENCIA PROTOTÍPICA
new Calculadora
__proto__
prototype
otros
Calculadora.prototype
__proto__
x 10 Calculadora.prototype.x = 10;
Calculadora.prototype.calcular = function() { ... }
constructor
calcular <fn>
HERENCIA PROTOTÍPICA
new Calculadora
__proto__
b prototype
__proto__ otros
y 20
var b = new Calculadora();
Calculadora.prototype
__proto__
x 10
HERENCIA PROTOTÍPICA
constructor
calcular <fn>
new Calculadora
__proto__
b prototype
__proto__ otros
y 20
var b = new Calculadora();
var c = new Calculadora();
Calculadora.prototype
__proto__
c x 10
HERENCIA PROTOTÍPICA
__proto__ constructor
y 20 calcular <fn>
new Calculadora
__proto__
b prototype
__proto__ otros
Function.Prototype
y 20
__proto__
y 20
Calculadora.prototype
__proto__
c x 10
Object.Protype
HERENCIA PROTOTÍPICA
__proto__ constructor
__proto__ null
y 20 calcular <fn>
y 20
1. obj = {}
2. obj.__proto__ = Person.prototype
HERENCIA PROTOTÍPICA
1. obj = {}
2. obj.__proto__ = otraCosa;
HERENCIA PROTOTÍPICA
3. return obj
Propiedades y herencia prototípica
padre.prop1 = "padre";
padre.prop1 === hijo.prop1; // true
HERENCIA PROTOTÍPICA
hijo.prop1 = "hijo";
padre.prop1 !== hijo.prop1; // true
Propiedades y herencia prototípica
hijo.prop2.subProp = 3;
padre.prop2.subProp === hijo.prop2.subProp; // true
HERENCIA PROTOTÍPICA
Herencia
function Sub() {
Base.call(this);
...
}
HERENCIA PROTOTÍPICA
Sub.prototype = Object(Base.prototype);
Sub.prototype.otroMetodo = function() { ... }
Herencia
Hijo.prototype.metodo = function() {
Base.prototype.metodo.call(this, ...);
...
}
HERENCIA PROTOTÍPICA
instanceof
o1 instanceof o2
o2.isPrototypeOf(o2)
Object.getPrototypeOf(o)
Devuelve el prototipo de o
HERENCIA PROTOTÍPICA
o.__proto__
Explorer
JS
ASYNC
Hosting environment
NodeJS
JS
ASYNC
Event Loop
Message Queue
clickBoton
ASYNC
Event Loop
Message Queue
hacerAlgo
ASYNC
Event Loop
Message Queue
hacerAlgo
esperarEjecucion
ASYNC
Event Loop
Message Queue
hacerAlgo
esperarEjecucion
setTimeout
ASYNC
Event Loop
Message Queue
hacerAlgo
esperarEjecucion
ASYNC
Event Loop
Message Queue
hacerAlgo
ASYNC
Event Loop
Message Queue
Call stack
clickBoton
ASYNC
Event Loop
Message Queue
clickBoton
ASYNC
Event Loop
Message Queue
clickBoton clickBoton
ASYNC
Callbacks
descargarDesdeUrl(‘www.urudata.com’);
ASYNC
Callbacks
descargarDesdeUrl(‘www.urudata.com’, descargaTerminada);
descargarDesdeUrl(‘www.urudata.com’, descargaTerminada);
function descargaTerminada(data) {
obtenerMetadata(data.metadataUrl, metadataObtenida);
La composición no es uniforme
Manejo de errores en callbacks
descargarDesdeUrl(‘www.urudata.com’, descargaTerminada);
function descargaTerminada(data) {
if(data.errors.length > 0)
throw new Error(“Error!”);
obtenerMetadata(data.metadataUrl, metadataObtenida);
}
ASYNC
Manejo de errores
var descarga = descargarDesdeUrl(‘www.urudata.com’);
return getUsername()
.then(function (username) {
return [username, getUser(username)];
})
.spread(function (username, user) {
...
});
funcs.forEach(function (f) {
result = result.then(f);
});
return result;
Q
Promises
return funcs.reduce(
function (soFar, f) {
return soFar.then(f);
}, Q(initialVal));
Q.delay(1000);
Q.timeout(promesa, 1000);
Q.promise(function(resolve,reject,notify){ ... })
Q
De dónde vienen las promesas?
Q.when($.get(...));
Q($.ajax(...)).then(function() {...});
Q
Deferreds
var q = Q.defer();
return deferred.promise;
Q
Deferreds
Deferred
Promise
Q
Deferreds
Deferred
Promise
.resolve .then
.reject
.notify
Q
Deferreds
Deferred
Promise
Pendings
.then(fn)
Q
Deferreds
Deferred
Promise
Pendings result = defer();
.then(fn)
Q
Deferreds
Deferred
Promise
Pendings result = defer();
callback = function(val) {
result.resolve(fn(val))
} .then(fn)
Q
Deferreds
Deferred
Promise
Pendings result = defer();
callback callback = function(val) {
result.resolve(fn(val))
} .then(fn)
Q
Deferreds
Deferred
Pendings
callback
Q
Deferreds
Deferred
Pendings .resolve(value)
callback
Q
Deferreds
Deferred
Pendings .resolve(value)
callback promise_value = ref(value)
Q
Deferreds
Deferred
Pendings .resolve(value)
promise_value = ref(value)
callback
Q
Deferreds
Deferred
Pendings .resolve(value)
promise_value = ref(value)
value.then(callback(promise_value))
Q
Deferreds
Deferred
Pendings .resolve(value)
promise_value = ref(value)
value.then(function(val) {
result.resolve(fn(val))
}) (promise_value));
Q
Promises
- Existen otras librerias como Q, RSVP, ES6, jQuery
- Q es compatible con las promesas de jQuery y otras libererías then-
able
Q
- Es una colección de helpers
- Responde a la pregunta “¿Qué necesito para empezar a ser
productivo inmediatamente?”
- Muchos de sus métodos responden a un enfoque funcional
UNDERSCORE.JS
Underscore.js
_.each(lista, iterador)
UNDERSCORE.JS
Underscore.js
_.each([1,2,3], alert)
UNDERSCORE.JS
Underscore.js
_.map(lista, iterador)
UNDERSCORE.JS
Underscore.js
_.find(lista, predicado)
Underscore.js
_.reduce([1,2,3],
function(memo,numero){ return memo + numero }, 0)
UNDERSCORE.JS
_.filter(lista, predicado)
UNDERSCORE.JS
Underscore.js
_.where(lista, propiedades)
UNDERSCORE.JS
Underscore.js
_.sortBy(lista, iterador)
UNDERSCORE.JS
Underscore.js
_.groupBy(lista, iterador)
UNDERSCORE.JS
Underscore.js
_.first(arr)
_.last(arr)
_.compact(arr)
_.flatten(arr)
UNDERSCORE.JS
_.uniq(arr)
_.zip(*arr)
Underscore.js
_.object(arr)
_.memoize(fn, [hash])
_.delay(fn, wait)
_.throttle(fn, wait)
UNDERSCORE.JS
_.debounce(fn, wait)
_.once(fn)
Underscore.js
_.keys(obj) _.reject(lista,predicado)
_.some(lista, [predicado])
UNDERSCORE.JS
_.every(lista,
[predicado])
_.max(lista, [iterador])
Underscore.js
_.iteratee()
_.iteratee(function(item) { ... })
_.iteratee(‘propiedad’)
UNDERSCORE.JS
_.chain(lista)
.map(fn)
.flatten()
.compact()
.sortBy(‘propiedad’)
.value()
UNDERSCORE.JS
Underscore.js
OO-style
_(lista).map(function(v) { ... })
UNDERSCORE.JS
Recorrimos mucho terreno rápidamente
Vimos algunas características del lenguaje y como nos permiten
aplicar ciertos patrones
Presentamos algunas librerías que resuelven problemas recurrentes o
mediante patrones y cambios de paradigma
Existen muchas otras librerías que podríamos recorrer como D3.js o
React.js
JS ya no es un lenguaje sólo web
Los navegadores modernos son cada vez más capaces y ofrecen cada
vez mas herramientas
Los frontends son cada vez más complejos y demandantes. Buen
diseño, buenos patrones y calidad son indispensables para desarrollar
soluciones escalables.
Esto es posible, pero requiere entender JS como un lenguaje
diferente.
Gracias!