TypeScript
¿Por qué TypeScript?
Nacimiento en 2012
Transpilador
Tipado fuerte
Código fuente y código compilado
Errores en tiempo de compilación
Complementa JS
Integración con el IDE
Angular
Entorno de desarrollo
IDE: Visual Studio Code
Configurar:
Format on Paste
Format on Save
tslint:autoFix on Save
NodeJS y npm
Comandos básicos
Clonar un repositorio:
git clone URL
Descargar última versión del repositorio:
git pull origin master
Configuración proxy
git config --global http.proxy http://username:password@host:port
git config --global https.proxy http://username:password@host:port
npm
Instalar última versión después de instalar Node.js
(configurar proxy si es necesario): npm install -g npm
Repositorio de módulos distribuibles
Módulos globales y módulos locales
La carpeta node_modules
El archivo package.json:
Registro de dependencias
Dependencias de desarrollo y de producción
Versiones (SEMVER)
scripts
Comandos npm
Instalar un paquete globalmente:
npm install -g paquete
Instalar un paquete de producción:
npm install paquete
Instalar un paquete de desarrollo:
npm install paquete --save-dev
Instalar todas las dependencias:
npm install
Instalar las dependencias de producción:
npm install --production
Listar paquetes instalados:
npm list --depth=0 (locales)Configuración proxy
npm config set proxy http://username:password@host:port
npm config set https-proxy http://username:password@host:port
JavaScript
Interpretado, compilado y ejecutado en el navegador
Cada navegador programa su propio motor de JS
Estandarización: ECMAScript
La versión ES6 o ES2015
Transpiladores: Babel, TypeScript
Organización del código JavaScript
Ejemplo de uso clásico de JS: utilizar un plugin de jQuery en nuestra web, o implementar alguna interacción con el usuario
Pocas líneas de código, todas en un mismo archivo
Organización del código JavaScript
(function($) {
$(document).ready(function() {
// Al hacer clic en una pestaña
$(".tab a").on("click", function(e) {
// Anulamos el link
e.preventDefault();
// Ocultamos todos los bloques de contenido
// y mostramos sólo el que se ha elegido
var content_id = $(this).attr("href");
$(".tab-content").hide();
$(content_id).show();
// Desmarcamos la pestaña que estuviera activa
// y marcamos la clicada como activa
$(".tab.active").removeClass("active");
$(this).closest(".tab").addClass("active");
})
})
})(jQuery);
<head>
<meta charset="UTF-8">
<title>Mi web</title>
<script src="vendor/jquery/jquery.min.js"></script>
<script src="js/tabs.js"></script>
</head>
24 líneas
Organización del código JavaScript
<head>
<meta charset="UTF-8">
<title>Mi web</title>
<script src="vendor/jquery/jquery.min.js"></script>
<script src="js/ui.js"></script>
</head>
(function($) {
$(document).ready(function() {
$(document).on('click', '.tab_new', offerGroupSwitchTabs);
$(document).on('click', '.navigationServices-li', jumpTo);
$('.load-more_new').on('click', loadMore).each(function() {
$(this).data('main', $(this).text());
});
})
var loadMore = function(e) {
e.preventDefault();
var $list = $(this).prev('.promos-list_new');
var button_text = $(this).data('main');
var button_alt_text = $(this).data('alt');
if ($(window).width() > 992) {
var hidden_classes = ".hidden";
var $hidden = $list.find(hidden_classes);
var n_show = 3;
} else if ($(window).width() > 768) {
var hidden_classes = ".hidden, .hidden-sm";
var $hidden = $list.find(hidden_classes);
var n_show = 2;
} else {
var hidden_classes = ".hidden, .hidden-sm, .hidden-xs";
var $hidden = $list.find(hidden_classes);
var n_show = 1;
}
if ($hidden.length == 0) {
$list.find(">li:nth-child(2)").addClass('hidden-xs');
$list.find(">li:nth-child(3)").addClass('hidden-xs hidden-sm');
$list.find(">li:nth-child(n+4)").addClass('hidden');
$(this).text(button_text);
} else {
$hidden.slice(0, n_show).each(function () {
$(this).removeClass(hidden_classes.replace(/[\.,\,]/g, ''));
});
if ($list.find(hidden_classes).length == 0) {
$(this).text(button_alt_text);
}
}
}
var offerGroupSwitchTabs = function(e) {
e.preventDefault();
var $info = $(this).closest('.info_new');
var target = $(this).attr('href');
var targetClass = target.replace('#', '.');
$info.find('.active').removeClass('active');
$info.find('[href=' + target + ']').addClass('active');
$(targetClass).addClass('active');
}
var jumpTo = function(e) {
e.preventDefault();
var target = $(this).find('a').attr('href');
var $target = $(target);
var targetTop = $target.offset().top;
$('html, body').animate({
scrollTop: targetTop - 200
}, {
duration: durationOnDistance(targetTop),
complete: function() {
window.location.hash = target;
}
});
}
var durationOnDistance = function(elementTop) {
var distance = elementTop - $(window).scrollTop();
var time = distance * 0.5;
return time;
}
})(jQuery)
75 líneas
Organización del código JavaScript
Programar toda la UI de una página
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var timerID = 0;
var c = document.getElementById('canvas')
var ctx = c.getContext('2d');
c.width = width;
c.height = height;
var speed = 10;
var size = 8;
var boids = [];
var totalBoids = 150;
var init = function(){
for (var i = 0; i < totalBoids; i++) {
boids.push({
x: Math.random() * width,
y: Math.random() * height,
v: {
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1
},
c: 'rgba(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ', 1.0)'
});
}
setInterval(update, 40);
}
var calculateDistance = function(v1, v2){
x = Math.abs(v1.x - v2.x);
y = Math.abs(v1.y - v2.y);
return Math.sqrt((x * x) + (y * y));
}
var checkWallCollisions = function(index){
if (boids[index].x > width) {
boids[index].x = 0;
}
else
if (boids[index].x < 0) {
boids[index].x = width;
}
if (boids[index].y > height) {
boids[index].y = 0;
}
else
if (boids[index].y < 0) {
boids[index].y = height;
}
}
var addForce = function(index, force){
boids[index].v.x += force.x;
boids[index].v.y += force.y;
magnitude = calculateDistance({
x: 0,
y: 0
}, {
x: boids[index].v.x,
y: boids[index].v.y
});
boids[index].v.x = boids[index].v.x / magnitude;
boids[index].v.y = boids[index].v.y / magnitude;
}
//This should be in multiple functions, but this will
//save tons of looping - Gross!
var applyForces = function(index){
percievedCenter = {
x: 0,
y: 0
};
flockCenter = {
x: 0,
y: 0
};
percievedVelocity = {
x: 0,
y: 0
};
count = 0;
for (var i = 0; i < boids.length; i++) {
if (i != index) {
//Allignment
dist = calculateDistance(boids[index], boids[i]);
//console.log(dist);
if (dist > 0 && dist < 50) {
count++;
//Alignment
percievedCenter.x += boids[i].x;
percievedCenter.y += boids[i].y;
//Cohesion
percievedVelocity.x += boids[i].v.x;
percievedVelocity.y += boids[i].v.y;
//Seperation
if (calculateDistance(boids[i], boids[index]) < 12) {
flockCenter.x -= (boids[i].x - boids[index].x);
flockCenter.y -= (boids[i].y - boids[index].y);
}
}
}
}
if (count > 0) {
percievedCenter.x = percievedCenter.x / count;
percievedCenter.y = percievedCenter.y / count;
percievedCenter.x = (percievedCenter.x - boids[index].x) / 400;
percievedCenter.y = (percievedCenter.y - boids[index].y) / 400;
percievedVelocity.x = percievedVelocity.x / count;
percievedVelocity.y = percievedVelocity.y / count;
flockCenter.x /= count;
flockCenter.y /= count;
}
addForce(index, percievedCenter);
addForce(index, percievedVelocity);
addForce(index, flockCenter);
}
var update = function(){
for (var i = 0; i < boids.length; i++) {
//Draw boid
ctx.beginPath();
ctx.strokeStyle = boids[i].c;
ctx.lineWidth = size;
ctx.moveTo(boids[i].x, boids[i].y);
boids[i].x += boids[i].v.x * speed;
boids[i].y += boids[i].v.y * speed;
applyForces(i);
ctx.lineTo(boids[i].x, boids[i].y);
ctx.stroke();
ctx.fill();
checkWallCollisions(i);
}
}
//Gui uses this to clear the canvas
var clearCanvas = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
}
init();
})();
1711 líneas
Organización del código JavaScript
¿2000 líneas en un solo archivo?
Ventajas
Inconvenientes
Organización del código JavaScript
Optimización: dividir el código en varios archivos/módulos
<head>
<meta charset="UTF-8">
<title>Mi web</title>
<script src="vendor/jquery/jquery.min.js"></script>
<script src="js/modules/tabs.js"></script>
<script src="js/modules/banners.js"></script>
<script src="js/modules/lightbox.js"></script>
<script src="js/modules/scroll.js"></script>
<script src="js/modules/carousel.js"></script>
<script src="js/modules/slideshow.js"></script>
<script src="js/modules/gallery.js"></script>
<script src="js/modules/navigation.js"></script>
</head>
Organización del código JavaScript
Ventajas
Inconvenientes
<head>
<meta charset="UTF-8">
<title>Mi web</title>
<script src="vendor/jquery/jquery.min.js"></script>
<script src="js/modules/tabs.js"></script>
<script src="js/modules/banners.js"></script>
<script src="js/modules/lightbox.js"></script>
<script src="js/modules/scroll.js"></script>
<script src="js/modules/carousel.js"></script>
<script src="js/modules/slideshow.js"></script>
<script src="js/modules/gallery.js"></script>
<script src="js/modules/navigation.js"></script>
</head>
Organización del código JavaScript
Dependencias: es difícil asegurar el orden, y no es posible tener dependencias circulares
<head>
<meta charset="UTF-8">
<title>Mi web</title>
<script src="vendor/jquery/jquery.min.js"></script>
<script src="js/modules/tabs.js"></script>
<script src="js/modules/banners.js"></script>
<script src="js/modules/lightbox.js"></script>
<script src="js/modules/scroll.js"></script>
<script src="js/modules/carousel.js"></script>
<script src="js/modules/slideshow.js"></script>
<script src="js/modules/gallery.js"></script>
<script src="js/modules/navigation.js"></script>
</head>
Organización del código JavaScript: módulos
Module loaders: ellos gestionan las dependencias y cargan los módulos (RequireJS, SystemJS)
Ventajas
Inconvenientes
Organización del código JavaScript: módulos
Module bundlers: además de lo anterior, generan un solo código encadenado y minificado (browserify, webpack)
Ventajas
Organización del código JavaScript: módulos
¿Puedo escribir mis módulos como yo quiera? ¿hay un estándar?
AMD: Asynchronous Module Definition
CommonJS
UMD: Universal Module Definition
ES6 Modules
define(['myModule', 'myOtherModule'], function(myModule, myOtherModule) {
return {
hello: function() {
console.log('hello');
},
goodbye: function() {
console.log('goodbye');
}
};
});
var myModuleA = require('myModuleA');
function myModuleB() {
this.hello = function() {
return 'hello!';
}
this.goodbye = function() {
return 'goodbye!';
}
}
module.exports = myModuleB;
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['myModule', 'myOtherModule'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('myModule'), require('myOtherModule'));
} else {
// Browser globals (Note: root is window)
root.returnExports = factory(root.myModule, root.myOtherModule);
}
}(this, function (myModule, myOtherModule) {
// Methods
function notHelloOrGoodbye(){}; // A private method
function hello(){}; // A public method because it's returned (see below)
function goodbye(){}; // A public method because it's returned (see below)
// Exposed public methods
return {
hello: hello,
goodbye: goodbye
}
}));
import { method1 } from './moduleA.js';
method1("hello");
export let method2 = function() {
console.log("Method 2");
}
Organización del código JavaScript: módulos
¿AMD, CommonJS, UMD, ES6?
Compatibilidad de los módulos ES6 en navegadores
¡Webpack!
TypeScript usa la sintaxis ES6
ES6
let y const
let a = 3;
let a = 10; // Error
var a = 12; // Error
const b = 10;
b = 3; // Error
const obj = {
x: 10,
y: 12
}
obj.x = 15; // OK
obj = { // Error
x: 15,
y: 12
}
ES6
let y const
Template literals
let nombre = "Antonio";
let cuadrado = function(x) {
return x * x;
}
let n = Math.floor(Math.random() * 10);
let saludo1 = "Hola, " + nombre + ". El cuadrado de " + n + " es " + cuadrado(n) + ".";
let saludo2 = `Hola, ${nombre}. El cuadrado de ${n} es ${cuadrado(n)}.`;
ES6
let y const
Template literals
for ... of
let nombres = ["Patricia", "Zacarías", "Miguel", "Maite"];
for (let i in nombres) {
console.log(nombres[i]);
}
for (let nombre of nombres) {
console.log(nombre);
}
let obj = {
x: 3,
y: 4
}
for (let i in obj) {
console.log(obj[i]);
}
let nombre = "Antonio Jesús";
for (let c of nombre) {
console.log(c);
}
ES6
let y const
Template literals
for ... of
Funciones
Parámetros por defecto
function potencia(x, y = 2) {
return Math.pow(x, y);
}
console.log(`10 elevado a 8 es ${potencia(10, 8)}`);
console.log(`El cuadrado de 5 es ${potencia(5)}`);
ES6
let y const
Template literals
for ... of
Funciones
Parámetros por defecto
Función arrow:
(parámetros) => expresión_devuelta;const potencia = function (x, y = 2) {
return Math.pow(x, y);
}
const potencia = (x, y = 2) => Math.pow(x, y);
setTimeout(() => console.log("pausa"), 2000);
ES6
Operador spread
Parámetros en funciones
Enviar varios parámetros a partir de un array
push y unshift
Intercalar un array dentro de otro
Copiar un array en otro
Copiar un objeto en otro
// function(a, b, c)
let nums = [1, 3, 6];
function sumar(a, b, c) {
console.log(a + b + c);
}
sumar(...nums);
// function(n parámetros)
let a = 3;
let b = 7;
let c = 8;
function sumar(...nums) {
let suma = 0;
for (n of nums) {
suma += n;
}
console.log("La suma es " + suma);
}
sumar(a, b, c);
// push y unshift
let nums1 = [1, 3, 6];
let nums2 = [0, 52, 15, 9];
nums1.push(...nums2);
console.log(nums1);
nums1.unshift(...nums2);
console.log(nums1);
// meter un array en medio de otra
let nums1 = [1, 3, 6];
let nums2 = [0, 52, 15, 9];
nums1.splice(1, 0, ...nums2);
console.log(nums1);
// copiar un array
let nums1 = [1, 3, 6];
let nums2 = [...nums1];
// mergear un objeto con defaults (ES2018)
let defaults = {
ancho: 100,
alto: 200,
color: "rojo"
}
let o1 = {
ancho: 200,
grosor: 10000
}
o1 = { ...defaults, ...o1 };
// convertir un NodeList a un array
let lis = [...document.getElementsByTagName("li")];
ES6
Clases
Propiedades y métodos
class A {
constructor(z) {
this.x = 3;
this.y = 10;
this.z = z;
}
suma() {
return this.x + this.y + this.z;
}
}
let a = new A(20);
console.log(a.suma());
ES6
Clases
Propiedades y métodos
Getters y setters
class A {
constructor(z) {
this.x = 3;
this.y = 10;
this.z = z;
}
suma() {
return this.x + this.y + this.z;
}
set zeta(z) {
this.z = z * 2;
}
get zeta() {
return this.z / 2;
}
}
let a = new A(20);
a.zeta = 15;
console.log(a.zeta);
ES6
Clases
Propiedades y métodos
Getters y setters
Métodos estáticos
class A {
constructor(z) {
this.x = 3;
this.y = 10;
this.z = z;
}
static getPI() {
return 3.14159;
}
suma() {
return this.x + this.y + this.z;
}
set zeta(z) {
this.z = z * 2;
}
get zeta() {
return this.z / 2;
}
}
let a = new A(20);
a.zeta = 15;
console.log(a.zeta);
console.log(A.getPI());
ES6
Clases
Propiedades y métodos
Getters y setters
Métodos estáticos
Herencia con extends y super()
class A {
constructor(z) {
this.x = 3;
this.y = 10;
this.z = z;
}
static getPI() {
return 3.14159;
}
suma() {
return this.x + this.y + this.z;
}
set zeta(z) {
this.z = z * 2;
}
get zeta() {
return this.z / 2;
}
}
class B extends A {
constructor() {
super(100);
this.x = 20;
}
suma() {
return this.x + this.z;
}
resta() {
return this.x - this.z;
}
}
let b = new B();
console.log(b.suma());
console.log(b.resta());
ES6
Módulos
import
import { literal } from 'ruta_modulo';Programación funcional con arrays
Métodos:
map
let nombres = ["juan", "luisa", "amparo", "arturo"];
nombres = nombres.map(nombre => nombre.toUpperCase());
console.log(nombres);
Programación funcional con arrays
Métodos:
map
filter
let personas = [
{
nombre: "juan",
edad: 15
},
{
nombre: "luisa",
edad: 35
},
{
nombre: "amparo",
edad: 17
},
{
nombre: "arturo",
edad: 32
}
];
let mayoresEdad = personas.filter(persona => persona.edad >= 18);
console.log(mayoresEdad);
Programación funcional con arrays
Métodos:
map
filter
reduce
let nums = [2, 4, 10, 15, 12];
let suma = nums.reduce((x, y) => x + y);
let objs = [
{
x: 3,
y: 2
},
{
x: 8,
y: 10
},
{
x: 10,
y: 15
}
]
let sumaX = objs.reduce((x, o2) => x + o2.x, 0); // Método 1
let sumaX = objs.map(o => o.x).reduce((x, y) => x + y); // Método 2
Programación funcional con arrays
Métodos:
map
filter
reduce
find
Encadenamiento
let notas = [
{
nombre: "juan",
nota: 6
},
{
nombre: "luisa",
nota: 8
},
{
nombre: "amparo",
nota: 4
},
{
nombre: "arturo",
nota: 3
}
];
let notasAprobados = notas.filter(n => n.nota >= 5).map(n => n.nota);
console.log(notasAprobados);
TypeScript
Superconjunto de JavaScript
Transpila a ES5 (o a otra versión)
TypeScript
Superconjunto de JavaScript
Transpila a ES5 (o a otra versión)
Tipado
Errores en tiempo de compilación
TypeScript
Superconjunto de JavaScript
Transpila a ES5 (o a otra versión)
Tipado
Errores en tiempo de compilación
tsc
{
"name": "ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "tsc --watch"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"tslint": "^5.11.0",
"typescript": "^3.0.3"
}
}
package.json
TypeScript
Superconjunto de JavaScript
Transpila a ES5 (o a otra versión)
Tipado
Errores en tiempo de compilación
tsc
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "./public/js/",
}
}
tsconfig.json
Tipos
Tipos básicos:
number
string
boolean
Array
any
void
let peso: number;
peso = 89.5;
let saludo: string;
saludo = 'Vais a petarlo con TypeScript';
let esVerano: boolean;
esVerano = false;
let nums: Array<number>;
nums = [10, 55, -3, 4.14];
let nombres: string[];
nombres = ['Juan', 'Paqui', 'Lorenzo', 'Alicia'];
let cosas: any[];
cosas = [10, 'Teruel', -5, true, [0, -10, 15], false];
function imprimeSaludo(s: string): void {
console.log(s);
}
imprimeSaludo('Buenas tardes');
Tipos
Tipos básicos:
number
string
boolean
Array
any
void
Enum
enum FormasPago {
TPV,
PayPal,
transferencia
}
let pago: FormasPago;
pago = FormasPago.PayPal;
procesarPago(pago);
function procesarPago(formaPago: FormasPago): void {
switch (formaPago) {
case FormasPago.TPV:
// ...
break;
case FormasPago.PayPal:
// ...
break;
case FormasPago.transferencia:
// ...
break;
}
}
Tipos
Tipos básicos:
number
string
boolean
Array
any
void
Enum
Union types
let numeros: Array<number | string>;
numeros = ['3', 6, '15.8', 0];
function procesar(a: string | number): void {
if (typeof a === 'string') {
console.log(a.toUpperCase());
} else {
console.log(a.toFixed(2));
}
}
Tipos
Tipos básicos:
number
string
boolean
Array
any
void
Enum
Union types
Genéricos
function verDoble<T>(elem: T): T[] {
let elemDoble: T[] = [elem, elem];
return elemDoble;
}
Tipos
Tipos básicos:
number
string
boolean
Array
any
void
Enum
Union types
Genéricos
Type assertion
const inputText = <HTMLInputElement>document.getElementById("nombre");
inputText.select();
Funciones
Sin flexibilidad en el número de parámetros
function sumar(a: number, b: number): number {
return a + b;
}
sumar(); // Error
sumar(3); // Error
sumar(10, 2); // OK
sumar(4, -3, 10, 8) // Error
Funciones
Sin flexibilidad en el número de parámetros
Parámetros opcionales
function sumar(a: number, b: number, c?: number): number {
if (c) {
return a + b + c;
} else {
return a + b;
}
}
sumar(10, 2);
sumar(10, 2, 15);
Funciones
Sin flexibilidad en el número de parámetros
Parámetros opcionales
Sobrecarga
function nChars(a: number): string;
function nChars(a: string): number;
function nChars(a: string | number): number | string {
if (typeof a === 'number') {
return '¡Es un número!';
} else if (typeof a === 'string') {
return a.length;
}
}
Funciones
Sin flexibilidad en el número de parámetros
Parámetros opcionales
Sobrecarga
Function types
function transformaNumero(x: number, callback: (n: number) => void) {
callback(x);
}
let a = 10;
transformaNumero(a, m => console.log(m * 2));
Módulos
Clases
class Factura {
numero: string;
base: number;
tipoIva: number;
constructor(numero: string, base: number, tipoIva: number = 21) {
this.numero = numero;
this.base = base;
this.tipoIva = tipoIva;
}
}
Clases
class Factura {
private static caracteresSerie = 2;
public num: string;
public serie: string;
public base: number;
private readonly intTipoIva: number;
constructor(base: number, tipoIva: number = 21) {
this.base = base;
this.intTipoIva = tipoIva;
}
get numero(): string {
return this.serie + this.num;
}
set numero(n: string) {
this.serie = n.slice(0, Factura.caracteresSerie - 1);
this.num = n.slice(Factura.caracteresSerie);
}
}
let f = new Factura(100);
f.numero = 'AB600';
console.log(f.numero);
Clases
abstract class Vehiculo {
public manual: boolean;
constructor(public ruedas: number, public motor: Motor) {
this.manual = this.motor === Motor.ninguno;
}
public abstract arrancar(): void;
}
class Bici extends Vehiculo {
public arrancar(): void {
console.log('Me pongo de pie y pedaleo');
}
}
Clases
interface Arrancable {
arrancar(): void;
apagar(): void;
}
abstract class Vehiculo {
public manual: boolean;
constructor(public ruedas: number, public motor: Motor) {
this.manual = this.motor === Motor.ninguno;
}
}
class Bici extends Vehiculo implements Arrancable {
public arrancar(): void {
console.log('Me pongo de pie y pedaleo');
}
public apagar(): void {
console.log('Me bajo de la bici');
}
}
interface Cliente {
id: number;
login: string;
nombre: string;
tipo: TiposCliente,
fechaAlta: Date;
}
function getClientes(): Cliente[] {
let clientes: Cliente[] = conectaBD('clientes');
return clientes;
}
Decoradores
@
Asignar metadatos
Muy utilizados en frameworks como Angular
Tipos:
de clase
de propiedad
de método
de parámetro
function Electrico(datos: { autonomia: number, bateriaExtraible: boolean }) {
return function (clase: Function): void {
clase.prototype.describir = function (): void {
console.log(`Soy un vehículo eléctrico, con una autonomía de ${datos.autonomia} horas
y mi batería ${datos.bateriaExtraible ? '' : 'no '}es extraíble.`);
}
}
}
@Electrico({
autonomia: 24,
bateriaExtraible: true
})
class Coche {
}
@Electrico({
autonomia: 6,
bateriaExtraible: false
})
class Bici {
}
let coche = new Coche();
coche.describir();
let bici = new Bici();
bici.describir();
function maxRuedas(target: Object, propertyKey: string) {
let valor = this[propertyKey];
function get() { return valor; }
function set(nuevoValor) {
if (nuevoValor > 8) { throw new Error('Máximo 8 puertas.'); }
valor = nuevoValor;
}
Object.defineProperty(target, propertyKey, {get, set});
}
class Coche {
@maxRuedas
public nRuedas: number;
constructor() {}
}
let c = new Coche();
c.nRuedas = 10; // Error
Links