adolfo sanz de diego

Anuncio
JAVASCRIPTAVANZADO
ADOLFOSANZDEDIEGO
OCTUBRE2015
1ACERCADE
1.1AUTOR
AdolfoSanzDeDiego
Blog:asanzdiego.blogspot.com.es
Correo:asanzdiego@gmail.com
GitHub:github.com/asanzdiego
Twitter:twitter.com/asanzdiego
Linkedin:in/asanzdiego
SlideShare:slideshare.net/asanzdiego
1.2LICENCIA
Esteobraestábajounalicencia:
CreativeCommonsReconocimientoCompartirIgual3.0
Elcódigofuentedelosprogramasestánbajouna
licencia:
GPL3.0
1.3EJEMPLOS
Lasslidesyloscódigosdeejemplolospodéis
encontraren:
https://github.com/asanzdiego/curso-javascriptavanzado-2015
2JAVASCRIPT
2.1HISTORIA
LocreaBrendanEichenNetscapeen1995para
hacerpáginaswebdinámicas
ApareceporprimeravezenNetscapeNavigator
2.0
Cadadíamásusado(clientesweb,videojuegos,
windows8,servidoresweb,basesdedatos,etc.)
2.2ELLENGUAJE
Orientadoaobjetos
Basadoenprototipos
Funcional
Débilmentetipado
Dinámico
3ORIENTACIÓNAOBJETOS
3.1¿QUÉESUNOBJETO?
Coleccióndepropiedades(paresnombre-valor).
Todosonobjetos(lasfuncionestambién)excepto
losprimitivos:strings,números,booleans,nullo
undefined
Parasabersiesunobjetoounprimitivohacer
typeofvariable
3.2PROPIEDADES(I)
Podemosaccederdirectamenteocomosifueseun
contenedor:
objeto.nombre===objeto[nombre]//true
3.3PROPIEDADES(II)
Podemoscrearlasydestruirlasentiempode
ejecución
varobjeto={};
objeto.nuevaPropiedad=1;//añadir
deleteobjeto.nuevaPropiedad;//eliminar
3.4OBJETOINICIADOR
Podemoscrearunobjetoasí:
varobjeto={
nombre:"Adolfo",
twitter:"@asanzdiego"
};
3.5FUNCIÓNCONSTRUCTORA
Oconunafunciónconstructorayunnew.
functionPersona(nombre,twitter){
this.nombre=nombre;
this.twitter=twitter;
};
varobjeto=newPersona("Adolfo","@asanzdiego");
3.6PROTOTIPOS(I)
Lasfuncionessonobjetosytienenunapropiedad
llamadaprototype.
Cuandocreamosunobjetoconnew,lareferencia
aesapropiedadprototypeesalmacenadaenuna
propiedadinterna.
Elprototiposeutilizaparacompartirpropiedades.
3.7PROTOTIPOS(II)
Podemosaccederalobjetoprototipodeunobjeto:
//FallaenOperaoIE<=8
Object.getPrototypeOf(objeto);
//NoesestandaryfallaenIE
objeto.__proto__;
3.8EFICIENCIA(I)
Siqueremosquenuestrocódigoseejecuteuna
solavezyqueprepareenmemoriatodolo
necesarioparagenerarobjetos,lamejoropciónes
usarunafunciónconstructorasoloconelestado
deunanuevainstancia,yelresto(losmétodos)
añadirlosalprototipo.
3.9EFICIENCIA(II)
Ejemplo:
functionConstructorA(p1){
this.p1=p1;
}
//losmétodoslosponenmosenelprototipo
ConstructorA.prototype.metodo1=function(){
console.log(this.p1);
};
3.10HERENCIA
Ejemplo:
functionConstructorA(p1){
this.p1=p1;
}
functionConstructorB(p1,p2){
//llamamosalsuperparaquenosepierdap1.
ConstructorA.call(this,p1);
this.p2=p2;
}
//HacemosqueBherededeA
//PrototipodeFunciónConstructoraBapuntaal
//PrototipodeFunciónConstructoraA
ConstructorB.prototype=Object.create(ConstructorA.prototype);
3.11CADENADEPROTOTIPOS
Cuandoseinvocaunallamadaaunapropiedad,
JavaScriptprimerobuscaenelpropioobjeto,ysi
noloencuentrabuscaensuprototipo,ysinoenel
prototipodelprototipo,asíhastaelprototipode
Objectqueesnull.
3.12CADENADEPROTOTIPOSDELAINSTANCIA
Enelejemploanterior:
instanciaB.__proto__==ConstructorB.prototype//true
instanciaB.__proto__.__proto__==ConstructorA.prototype//true
instanciaB.__proto__.__proto__.__proto__==Object.prototype//true
instanciaB.__proto__.__proto__.__proto__.__proto__==null//true
3.13CADENADEPROTOTIPOSDELAFUNCIÓN
CONSTRUCTORA
Enelejemploanterior:
expect(ConstructorB.__proto__).toEqual(Function.prototype);
expect(ConstructorB.__proto__.__proto__).toEqual(Object.prototype);
expect(ConstructorB.__proto__.__proto__.__proto__).toEqual(null);
3.14ESQUEMAPROTOTIPOS
Esquemaprototipos
3.15OPERADORINSTANCEOF
LaexpresióninstanciaBinstanceofConstructorA
devolverátrue,sielprototipodelaFunción
ConstructorA,seencuentraenlacadenade
prototiposdelainstanciaB.
Enelejemploanterior:
instanciaBinstanceofConstructorB;//true
instanciaBinstanceofConstructorA;//true
instanciaBinstanceofObject;//true
3.16EXTENSIÓN
Conlosprototipospodemosextenderla
funcionalidaddelpropiolenguaje.
Ejemplo:
String.prototype.hola=function(){
return"Hola"+this;
}
"Adolfo".hola();//"HolaAdolfo"
3.17PROPIEDADESYMÉTODOSESTÁTICOS(I)
Loquesedefinedentrodelafunciónconstructora
vaaserpropiodelainstancia.
Perocomohemosdicho,enJavaScript,una
funciónesunobjeto,alquepodemosañadirtanto
atributoscomofunciones.
Añadiendoatributosyfuncionesalafunción
constructoraobtenemospropiedadesymétodos
estáticos.
3.18PROPIEDADESYMÉTODOSESTÁTICOS(II)
Ejemplo:
functionConstructorA(){
ConstructorA.propiedadEstatica="propiedadestática";
}
ConstructorA.metodoEstatico=function(){
console.log("métodoestático");
}
3.19PROPIEDADESYMÉTODOSPRIVADOS(I)
Lavisibilidaddeobjetosdependedelcontexto.
LoscontextosenJavaScriptsonbloquesdecódigo
entredos{}yengeneral,desdeunodeellos,solo
tienesaccesoaloqueenélsedefinayaloquese
definaenotroscontextosquecontenganaltuyo.
3.20PROPIEDADESYMÉTODOSPRIVADOS(II)
Ejemplo:
functionConstructorA(privada,publica){
varpropiedadPrivada=privada;
this.propiedadPublica=publica;
varmetodoPrivado=function(){
console.log("-->propiedadPrivada",propiedadPrivada);
}
this.metodoPublico=function(){
console.log("-->propiedadPublica",this.propiedadPublica);
metodoPrivado();
}
}
3.21POLIMORFISMO
Poderllamaramétodossintácticamenteiguales
deobjetosdetiposdiferentes.
Estoseconsiguemedianteherencia.
4TÉCNICASAVANZADAS
4.1FUNCIONES
Sonobjetosconsuspropiedades.
Sepuedenpasarcomoparámetrosaotras
funciones.
Puedenguardarseenvariables.
Sonmensajescuyoreceptoresthis.
4.2THIS
Ejemplo:
varnombre="Laura";
varalba={
nombre:"Alba",
saludo:function(){
return"Hola"+this.nombre;
}
}
alba.saludo();//HolaAlba
varfn=alba.saludo;
fn();//HolaLaura
4.3CALLYAPPLY
Dosfuncionespermitenmanipularelthis:cally
applyqueenloúnicoquesediferencianesenla
llamada.
fn.call(thisArg[,arg1[,arg2[...]]])
fn.apply(thisArg[,arglist])
4.4NÚMEROVARIABLEDEARGUMENTOS
LasfuncionesenJavaScriptaunquetengan
especificadounnúmerodeargumentosde
entrada,puedenrecibirmásomenosargumentos
yesválido.
4.5ARGUMENTS
Esunobjetoquecontienelosparámetrosdela
función.
functionechoArgs(){
console.log(arguments[0]);//Adolfo
console.log(arguments[1]);//Sanz
}
echoArgs("Adolfo","Sanz");
4.6DECLARACIÓNDEFUNCIONES
Estas2declaracionessonequivalentes:
functionholaMundo1(){
console.log("HolaMundo1");
}
holaMundo1();
varholaMundo2=function(){
console.log("HolaMundo2");
}
holaMundo2();
4.7TRANSFIRIENDOFUNCIONESAOTRAS
FUNCIONES
Hemosdichoquelasfuncionessonobjetos,así
quesepuedenpasarcomoparámetros.
functionsaluda(){
console.log("Hola")
}
functionejecuta(func){
func()
}
ejecuta(saluda);
4.8FUNCIONESANÓNIMAS(I)
Hemosdichoquelasfuncionessepueden
declarar.
Perotambiénpodemosnodeclararlasydejarlas
comoanónimas.
4.9FUNCIONESANÓNIMAS(II)
Unafunciónanónimaasídeclaradanosepodría
ejecutar.
function(nombre){
console.log("Hola"+nombre);
}
4.10FUNCIONESANÓNIMAS(III)
Perounafunciónpuededevolverunafunción
anónima.
functionsaludador(nombre){
returnfunction(){
console.log("Hola"+nombre);
}
}
varsaluda=saludador("mundo");
saluda();//Holamundo
4.11FUNCIONESAUTOEJECUTABLES
Podemosautoejecutarfuncionesanónimas.
(function(nombre){
console.log("Hola"+nombre);
})("mundo")
4.12CLOUSURES(I)
Unclosurecombinaunafunciónyelentornoen
quesecreó.
functioncreaSumador(x){
returnfunction(y){
returnx+y;
};
}
varsuma5=creaSumador(5);
varsuma10=creaSumador(10);
console.log(suma5(2));//muestra7
console.log(suma10(2));//muestra12
4.13CLOUSURES(II)
Enunaclosureslafuncióninternaalmacenauna
referenciaalúltimovalordelavariable
establecidocuandolafunciónexternaterminade
ejecutarse.
4.14ELPATRÓNMODULO
Setratadeunafunciónqueactúacomo
contenedorparauncontextodeejecución.
miModulo=(function(){
varpropiedadPrivada;
functionmetodoPrivado(){};
//APIpublica
return{
metodoPublico1:function(){
},
metodoPublico2:function(){
}
}
}());
4.15EFICIENCIA(I)
Siseejecutadesdeelnavegador,sesuelepasar
comoparámetroelobjetowindowparamejorarel
rendimiento.Asícadavezquelonecesitemosel
intérpreteloutilizarádirectameteenlugarde
buscarloremontandoniveles.
Ytambiénsesuelepasarelparámetroundefined,
paraevitarloserroresquepuedendarsesila
palabrareservadahasidoreescritaenalguna
partedelcódigoysuvalornocorrespondaconel
esperado.
4.16EFICIENCIA(II)
miModulo=(function(window,undefined){
//Elcódigovaaquí
})(window);
4.17ELPATRÓNMODULOREVELADO(I)
ElproblemadelpatrónModuloespasarunmétodo
deprivadoapúblicooviceversa.
Poresemotivoloquequesesuelehaceresdefinir
todoenelcuerpo,yluegoreferenciarsololos
públicosenelbloquereturn.
4.18ELPATRÓNMODULOREVELADO(II)
miModulo=(function(){
functionmetodoA(){};
functionmetodoB(){};
functionmetodoC(){};
//APIpublica
return{
metodoPublico1:metodoA,
metodoPublico2:metodoB
}
}());
4.19ESPACIOSDENOMBRES(I)
Parasimularespaciosdenombres,enJavaScript
seanidanobjetos.
miBiblioteca=miBiblioteca||{};
miBiblioteca.seccion1=miBiblioteca.seccion1||{};
miBiblioteca.seccion1={
priopiedad:p1,
metodo:function(){},
};
miBiblioteca.seccion2=miBiblioteca.seccion2||{};
miBiblioteca.seccion2={
priopiedad:p2,
metodo:function(){},
};
4.20ESPACIOSDENOMBRES(II)
Sepuedecombinarloanteriorconmódulos
autoejecutables:
miBiblioteca=miBiblioteca||{};
(function(namespace){
varpropiedadPrivada=p1;
namespace.propiedadPublica=p2;
varmetodoPrivado=function(){};
namespace.metodoPublico=function(){};
}(miBiblioteca));
5DOCUMENTOBJECTMODEL
5.1¿QUÉESDOM?
AcrónimodeDocumentObjectModel
Esunconjuntodeutilidadesespecíficamente
diseñadasparamanipulardocumentosXML,ypor
extensióndocumentosXHTMLyHTML.
DOMtransformainternamenteelarchivoXMLen
unaestructuramásfácildemanejarformadapor
unajerarquíadenodos.
5.2TIPOSDENODOS
Losmásimportantesson:
Document:representaelnodoraíz.
Element:representaelcontenidodefinidopor
unpardeetiquetasdeaperturaycierreypuede
tenertantonodoshijoscomoatributos.
Attr:representaelatrributodeunelemento.
Text:almacenaelcontenidodeltextoquese
encuentraentreunaetiquetadeaperturayuna
decierre.
5.3RECORRERELDOM
JavaScriptproporcionafuncionespararecorrerlos
nodos:
getElementById(id)
getElementsByName(name)
getElementsByTagName(tagname)
getElementsByClassName(className)
getAttribute(attributeName)
querySelector(selector)
querySelectorAll(selector)
5.4MANIPULARELDOM
JavaScriptproporcionafuncionesparala
manipulacióndenodos:
createElement(tagName)
createTextNode(text)
createAttribute(attributeName)
appendChild(node)
insertBefore(newElement,targetElement)
removeAttribute(attributename)
removeChild(childreference)
replaceChild(newChild,oldChild)
5.5PROPIEDADESNODOS(I)
Losnodostienenalgunaspropiedadesmuyútiles:
attributes[]
className
id
innerHTML
nodeName
nodeValue
style
tabIndex
tagName
title
5.6PROPIEDADESNODOS(II)
Losnodostienenalgunaspropiedadesmuyútiles:
childNodes[]
firstChild
lastChild
previousSibling
nextSibling
ownerDocument
parentNode
6LIBRERÍASYFRAMEWORKS
6.1JQUERY
jQuery:libreriaquereducecódigo("writeless,do
more").
//VanillaJavaScript
varelem=document.getElementById("miElemento");
//jQuery
varelem=$("#miElemento");
6.2JQUERYUI&MOBILE
jQueryUI:diseñointerfacesgráficas.
jQueryMobile:versiónadaptadaparamóviles
(eventosytamaño).
6.3FRAMEWORKSCSS
BootstrapyFoundation.
Fácilmaquetación,sistemarejilla,clasesCSS,
temas,etc.
6.4MVCENELFRONT
BackboneJS:ligeroyflexible.
EmberJS:"ConventionoverConfiguration",muy
popularentredesarrolladoresRubyonRails.
AngularJSextiendeetiquetasHML(g-app,ngcontroller,ng-model,ng-view),detrásestáGoogle,
tienegranpopularidad,abruptacurvade
aprendizaje.
6.5NODEJS
NodeJSpermiteejecutarJSfueradelnavegador.
Vieneconsupropiogestordepaquetes:npm
6.6AUTOMATIZACIÓNDETAREAS
GruntJS:máspopularidadymásplugins.
GulpJS:másrápidotantoalescribir("Codeover
Configure")comoalejecutar(streams).
6.7GESTIÓNDEDEPENDENCIAS
Bower:paraelladocliente.Puedetrabajarcon
repositoriosGit.
Browserify:permiteescribirmóduloscomoen
NodeJSycompilarlosparaquesepuedanusaren
elnavegador.
RequeriJS:lasdependenciassecargandeforma
asíncronaysolocuandosenecesitam.
WebPack:esunempaquetadordemódulos
6.8APLICACIONESDEESCRITORIO
MULTIPLATAFORMA
AppJS,ysuforkDeskShell:losmásantiguos,un
pocoabandonados.
NW.js:opciónmáspopularymadurahoyendía.
Electron:creadaparaeleditorAtomdeGitHub:
estácreciendoenpopularidad.
6.9APLICACIONESMÓVILESHÍBRIDAS
cordova:unadelosprimeros.Hoyendía,otros
frameworkssebasanenél.
ionic:utilizaAngularJS,tieneunaCLI,muypopular.
ReactNative:reciénliberadoporfacebook.
6.10WEBCOMPONENTS
WebComponentsesunaespecificacióndelaW3C
parapermitircrearcomponentesyreutilizarlos.
polymer:proyectodeGoogleparapoderempezar
ausarlosWebComponentsentodoslos
navegadores.
6.11OTROS
React:libreríahechoporFacebookparacrear
interfacesqueserenderizanmuyrápido,yasea
enclienteoservidor.
Flux:frameworkhechoporFacebookqueutiliza
React.
Meteor:esunaplataformaquepermitedesarrollar
aplicacionesreal-timeconJSIsomófico(seejecuta
enfrontyback)
7EVENTOS
7.1ELPATRÓNPUBSUB(I)
varEventBus={
topics:{},
subscribe:function(topic,listener){
if(!this.topics[topic])this.topics[topic]=[];
this.topics[topic].push(listener);
},
publish:function(topic,data){
if(!this.topics[topic]||this.topics[topic].length<1)return;
this.topics[topic].forEach(function(listener){
listener(data||{});
});
}
};
7.2ELPATRÓNPUBSUB(II)
EventBus.subscribe('foo',alert);
EventBus.publish('foo','HelloWorld!');
7.3ELPATRÓNPUBSUB(III)
varMailer=function(){
EventBus.subscribe('order/new',this.sendPurchaseEmail);
};
Mailer.prototype={
sendPurchaseEmail:function(userEmail){
console.log("Sentemailto"+userEmail);
}
};
7.4ELPATRÓNPUBSUB(IV)
varOrder=function(params){
this.params=params;
};
Order.prototype={
saveOrder:function(){
EventBus.publish('order/new',this.params.userEmail);
}
};
7.5ELPATRÓNPUBSUB(V)
varmailer=newMailer();
varorder=newOrder({userEmail:'john@gmail.com'});
order.saveOrder();
"Sentemailtojohn@gmail.com"
7.6PRINCIPALESEVENTOS(I)
Evento
Descripción
onblur
Unelementopierdeelfoco
onchange
Unelementohasidomodificado
onclick
Pulsarysoltarelratón
ondblclick
Pulsardosvecesseguidasconelratón
7.7PRINCIPALESEVENTOS(II)
Evento
Descripción
onfocus
Unelementoobtieneelfoco
onkeydown
Pulsarunateclaynosoltarla
onkeypress
Pulsarunatecla
onkeyup
Soltarunateclapulsada
onload
Páginacargadacompletamente
7.8PRINCIPALESEVENTOS(III)
Evento
Descripción
onmousedown
Pulsarunbotóndelratónyno
soltarlo
onmousemove
Moverelratón
onmouseout
Elratón"sale"delelemento
onmouseover
Elratón"entra"enelelemento
onmouseup
Soltarelbotóndelratón
7.9PRINCIPALESEVENTOS(IV)
Evento
Descripción
onreset
Inicializarelformulario
onresize
Modificareltamañodelaventana
onselect
Seleccionaruntexto
onsubmit Enviarelformulario
onunload
Seabandonalapágina
7.10SUSCRIPCIÓN
ParaañadiroeliminarunListenerdeuneventoa
unelemento:
varwindowOnLoad=function(e){
console.log('window:load',e);
};
window.addEventListener('load',windowOnLoad);
window.removeEventListener('load',windowOnLoad);
7.11EVENTOSPERSONALIZADOS(I)
Podemoscreareventospersonalizados:
varevent=newEvent('build');
elem.addEventListener('build',function(e){...},false);
7.12EVENTOSPERSONALIZADOS(II)
Podemoscreareventospersonalizadoscondatos:
varevent=newCustomEvent('build',{'detail':detail});
elem.addEventListener('build',function(e){
log('Thetimeis:'+e.detail);
},false);
7.13DISPARARUNEVENTO
Podemosdisparareventos:
functionsimulateClick(){
varevent=newMouseEvent('click');
varelement=document.getElementById('id');
element.dispatchEvent(event);
}
7.14PROPAGACIÓN(I)
12
||/\
+-------------||------------||-------------+
|DIV1|||||
|+---------||------------||---------+|
||DIV2||||||
||+-----||------------||-----+||
|||A\/|||||
||+----------------------------+||
|+------------------------------------+|
|FASEDEFASEDE|
|CAPTURABURBUJA|
|DEEVENTOSDEEVENTOS|
+--------------------------------------------+
7.15PROPAGACIÓN(II)
//enfasedeCAPTURA
addEventListener("eventName",callback,true);
//enfasedeBURBUJA
addEventListener("eventName",callback,false);//pordefecto
7.16PROPAGACIÓN(III)
//detienelapropagacióndelevento
event.stopPropagation();
//eliminalasaccionespordefecto(ejemplo:abrirenlace)
event.preventDefault();
8WEBSOCKETS
8.1¿QUÉSONLOSWEBSOCKETS?
Nospermitencomunicaciónbidireccionalentre
clienteyservidor.
8.2SOCKET.IO
Libreríaclienteyservidor(NodeJS)parautilizar
WebSockets:
SimplificalaAPI.
Permiteenvíarnosólotexto.
Permitecreareventospropios.
Permiteutilizarnavegadoressinsoportede
WebSockets.
9AJAX
9.1¿QUÉESAJAX?
AcrónimodeAsynchronousJavaScriptAndXML.
Técnicaparacrearaplicacioneswebinteractivaso
RIA(RichInternetApplications).
Estasaplicacionesseejecutanenelcliente,es
decir,enelnavegadordelosusuarios.
Mientrassemantienelacomunicaciónasíncrona
conelservidorensegundoplano.
Deestaformaesposiblerealizarcambiossobre
laspáginassinnecesidadderecargarlas.
9.2TECNOLOGÍASAJAX
AJAXnoesunatecnologíaensímisma,en
realidad,setratadevariastecnologías
independientesqueseunendeformasnuevasy
sorprendentes.
LastecnologíasqueformanAJAXson:
XHTMLyCSS,comoestándaresde
presentación.
DOM,paralamanipulacióndinámicadela
presentación.
XML,JSONyotros,paralalamanipulaciónde
información.
XMLHttpRequest,paraelintercambioasíncrono
deinformación.
JavaScript,paraunirtodaslasdemás
tecnologías.
9.3¿QUÉESELXMLHTTPREQUEST?
ElintercambiodedatosAJAXentreclientey
servidorsehacemedianteelobjeto
XMLHttpRequest,disponibleenlosnavegadores
actuales.
Noesnecesarioqueelcontenidoestéformateado
enXML.
Sumanejopuedellegarasercomplejo,aunque
libreríascomojQueryfacilitanenormementesu
uso.
9.4EJEMPLO
varhttp_request=newXMLHttpRequest();
varurl="http://example.net/jsondata.php";
//DescargalosdatosJSONdelservidor.
http_request.onreadystatechange=handle_json;
http_request.open("GET",url,true);
http_request.send(null);
functionhandle_json(){
if(http_request.status==200){
varjson_data=http_request.responseText;
varthe_object=eval("("+json_data+")");
}else{
alert("OcurriounproblemaconlaURL.");
}
}
10JSON
10.1¿QUÉESJSON?
AcrónimodeJavaScriptObjectNotation.
Esunsubconjuntodelanotaciónliteraldeobjetos
deJavaScript.
Sirvecomoformatoligeroparaelintercambiode
datos.
Susimplicidadhageneralizadosuuso,
especialmentecomoalternativaaXMLenAJAX.
EnJavaScript,untextoJSONsepuedeanalizar
fácilmenteusandolafuncióneval().
10.2PARSE
miObjeto=eval('('+json_datos+')');
Evalesmuyrápido,perocomocompilayejecuta
cualquiercódigoJavaScript,lasconsideracionesde
seguridadrecomiendannousarlo.
LorecomendableusarlaslibreríasdeJSON.org:
JSONinJavaScript-Explanation
JSONinJavaScript-Downloads
10.3EJEMPLO
{
curso:"AJAXyjQuery",
profesor:"Adolfo",
participantes:[
{nombre:"Isabel",edad:35},
{nombre:"Alba",edad:15},
{nombre:"Laura",edad:10}
]
}
10.4JSONP
PorseguridadXMLHttpRequestsólopuederealizar
peticionesalmismodominio.
JSONPenvuelveelJSONenunafuncióndefinida
porelcliente.
EstonospermitehacerpeticionesGET(sóloGET)
adominiosdistintos.
10.5CORS(I)
ProtocoloCross-OriginResourceSharing
(Comparticiónderecursosdedistintosorígenes).
Realizarpeticionesaotrosdominiossiemprey
cuandoeldominiodedestinoestédeacuerdoen
recibirpeticionesdeldominiodeorigen.
Tantonavegadorcomoservidortienenque
implementarelprotocolo.
10.6CORS(II)
Desdeelservidor,seenvíaencabecera:
Access-Control-Allow-Origin:http://dominio-permitido.com
11APISREST
11.1¿QUÉESUNAPIREST?
REST(RepresentationalStateTransfer)esuna
técnicadearquitecturasoftwareparasistemas
hipermediadistribuidoscomolaWorldWideWeb.
Esdecir,unaURL(UniformResourceLocator)
representaunrecursoalquesepuedeaccedero
modificarmediantelosmétodosdelprotocolo
HTTP(POST,GET,PUT,DELETE).
11.2¿PORQUÉREST?
Esmássencillo(tantolaAPIcomola
implementación).
Esmásrápido(peticionesmásligerasquese
puedecachear).
Esmultiformato(HTML,XML,JSON,etc.).
SecomplementamuybienconAJAX.
11.3EJEMPLOAPI
GETahttp://myhost.com/person
Devuelvetodaslaspersonas
POSTahttp://myhost.com/person
Crearunanuevapersona
GETahttp://myhost.com/person/123
Devuelvelapersonaconid=123
PUTahttp://myhost.com/person/123
Actualizalapersonaconid=123
DELETEahttp://myhost.com/person/123
Borralapersonaconid=123
11.4ERRORESHTTP
200OK
201Created
202Accepted
301MovedPermanently
400BadRequest
401Unauthorised
402PaymentRequired
403Forbidden
404NotFound
405MethodNotAllowed
500InternalServerError
501NotImplemented
12GESTIÓNDEDEPENDENCIAS
12.1AMD
DefinicióndeMódulosAsíncronos(AMD)
Laimplementaciónmáspopulardeesteestándar
esRequireJS.
Sintaxisunpococomplicada.
Permitelacargademódulosdeformaasíncrona.
Seusaprincipalmenteennavegadores.
12.2REQUIREJS(I)
index.html
<!DOCTYPEhtml>
<html>
<head>
<title>Page1</title>
<scriptdata-main="js/index"src="js/lib/require.js"></script>
</head>
<body>
<h1>HolaMundo</h1>
</body>
</html>
12.3REQUIREJS(II)
js/index.js
requirejs(['./common'],function(common){
requirejs(['app/main']);
});
12.4REQUIREJS(III)
app/main.js
define(function(require){
var$=require('jquery');
varpersona=require('./persona');
$('h1').html("Holarequery.js");
varp=newpersona("Adolfo",30);
p.saludar();
});
12.5REQUIREJS(IV)
app/persona.js
define(function(){
varPersona=function(nombre,edad){
this.nombre=nombre;
Persona.prototype.saludar=function(){
alert("Hola,minombrees"+this.nombre);
};
}
returnPersona;
});
12.6COMMONJS
LaimplementaciónusadaenNodeJSyBrowserify.
Sintaxissencilla.
Cargalosmódulosdeformasíncrona.
Seusaprincipalmenteenelservidor.
12.7BROWSERIFY(I)
Instalarbrowserify
npminstall-gbrowserify
12.8BROWSERIFY(II)
Instalardependenciasdepackage.json
npminstall
12.9BROWSERIFY(III)
package.json
{
"name":"browserify-example",
"version":"1.0.0",
"dependencies":{
"jquery":"^2.1.3"
}
}
12.10BROWSERIFY(IV)
Compilarlasdependenciasabundle.js
browserifyjs/main.js-ojs/bundle.js
12.11BROWSERIFY(V)
index.html
<!doctypehtml>
<html>
<head>
<title>BrowserifyPlayground</title>
</head>
<body>
<h1>HolaMundo</h1>
<scriptsrc="js/bundle.js"></script>
</body>
</html>
12.12BROWSERIFY(VI)
js/app/main.js
var$=require('jquery');
varpersona=require('./persona');
$('h1').html('HolaBrowserify');
varp=newpersona("Adolfo",30);
p.saludar();
12.13BROWSERIFY(VII)
js/app/persona.js
varPersona=function(nombre,edad){
this.nombre=nombre;
Persona.prototype.saludar=function(){
alert("Hola,minombrees"+this.nombre);
};
}
module.exports=Persona;
12.14ECMASCRIPT6
Cojelomejordelos2enfoques:
SimilitudesconCommonJS:sintaxissencilla.
SimilitudesconAMD:soporteparacarga
asíncrona.
13ES6
13.1COMOUSARLOHOY
BabelnospermiteutilizarES6hoyendía.
13.2FUNCIÓNARROW(I)
//ES5
vardata=[{...},{...},{...},...];
data.forEach(function(elem){
console.log(elem)
});
13.3FUNCIÓNARROW(I)
//ES6
vardata=[{...},{...},{...},...];
data.forEach(elem=>{
console.log(elem);
});
13.4FUNCIÓNARROW(III)
//ES5
varmiFuncion=function(num1,num2){
returnnum1+num2;
}
13.5FUNCIÓNARROW(IV)
//ES6
varmiFuncion=(num1,num2)=>num1+num2;
13.6THIS(I)
//ES5
varobjEJ5={
data:["Adolfo","Isabel","Alba"],
duplicar:function(){
varthat=this;
this.data.forEach(function(elem){
that.data.push(elem);
});
returnthis.data;
}
}
13.7THIS(II)
//ES6
varobjEJ6={
data:["Adolfo","Isabel","Alba"],
duplicar:function(){
this.data.forEach((elem)=>{
this.data.push(elem);
});
returnthis.data;
}
}
13.8DEFINICIÓNDECLASES(I)
//ES5
varShape=function(id,x,y){
this.id=id;
this.move(x,y);
};
Shape.prototype.move=function(x,y){
this.x=x;
this.y=y;
};
13.9DEFINICIÓNDECLASES(II)
//ES6
classShape{
constructor(id,x,y){
this.id=id
this.move(x,y)
}
move(x,y){
this.x=x
this.y=y
}
}
13.10HERENCIADECLASES(I)
//ES5
varRectangle=function(id,x,y,width,height){
Shape.call(this,id,x,y);
this.width=width;
this.height=height;
};
Rectangle.prototype=Object.create(Shape.prototype);
Rectangle.prototype.constructor=Rectangle;
varCircle=function(id,x,y,radius){
Shape.call(this,id,x,y);
this.radius=radius;
};
Circle.prototype=Object.create(Shape.prototype);
Circle.prototype.constructor=Circle;
13.11HERENCIADECLASES(II)
//ES6
classRectangleextendsShape{
constructor(id,x,y,width,height){
super(id,x,y)
this.width=width
this.height=height
}
}
classCircleextendsShape{
constructor(id,x,y,radius){
super(id,x,y)
this.radius=radius
}
}
13.12LET(I)
//ES5
(function(){
console.log(x);//xnoestádefinidaaún.
if(true){
varx="holamundo";
}
console.log(x);
//Imprime"holamundo",porque"var"
//hacequeseaglobalalafunción;
})();
13.13LET(II)
//ES6
(function(){
if(true){
letx="holamundo";
}
console.log(x);
//Daerror,porque"x"hasidodefinidadentrodel"if"
})();
13.14SCOPES(I)
//ES5
(function(){
varfoo=function(){return1;}
foo()===1;
(function(){
varfoo=function(){return2;}
foo()===2;
})();
foo()===1;
})();
13.15SCOPES(II)
//ES6
{
functionfoo(){return1}
foo()===1
{
functionfoo(){return2}
foo()===2
}
foo()===1
}
13.16CONST(I)
//ES6
(function(){
constPI;
PI=3.15;
//ERROR,porquehadeasignarseunvalorenladeclaración
})();
13.17CONST(II)
//ES6
(function(){
constPI=3.15;
PI=3.14159;
//ERRORdenuevo,porqueesdesólo-lectura
})();
13.18TEMPLATESTRINGS(I)
//ES6
letnombre1="JavaScript";
letnombre2="awesome";
console.log(`Sóloquierodecirque${nombre1}is${nombre2}`);
//SoloquierodecirqueJavaScriptisawesome
13.19TEMPLATESTRINGS(II)
//ES5
varsaludo="ola"+
"que"+
"ase";
13.20TEMPLATESTRINGS(III)
//ES6
varsaludo=`ola
que
ase`;
13.21DESTRUCTURING(I)
//ES6
var[a,b]=["hola","mundo"];
console.log(a);//"hola"
console.log(b);//"mundo"
13.22DESTRUCTURING(II)
//ES6
varobj={nombre:"Adolfo",apellido:"Sanz"};
var{nombre,apellido}=obj;
console.log(nombre);//"Adolfo"
console.log(apellido);//"Sanz"
13.23DESTRUCTURING(III)
//ES6
varfoo=function(){
return["180","78"];
};
var[estatura,peso]=foo();
console.log(estatura);//180
console.log(peso);//78
13.24PARÁMETROSCONNOMBRE(I)
//ES5
functionf(arg){
varname=arg[0];
varval=arg[1];
console.log(name,val);
};
functiong(arg){
varn=arg.name;
varv=arg.val;
console.log(n,v);
};
functionh(arg){
varname=arg.name;
varval=arg.val;
console.log(name,val);
};
f(["bar",42]);
g({name:"foo",val:7});
h({name:"bar",val:42});
13.25PARÁMETROSCONNOMBRE(II)
//ES6
functionf([name,val]){
console.log(name,val)
}
functiong({name:n,val:v}){
console.log(n,v)
}
functionh({name,val}){
console.log(name,val)
}
f(["bar",42])
g({name:"foo",val:7})
h({name:"bar",val:42})
13.26RESTOPARÁMETROS(I)
//ES5
functionf(x,y){
vara=Array.prototype.slice.call(arguments,2);
return(x+y)*a.length;
};
f(1,2,"hello",true,7)===9;
13.27RESTOPARÁMETROS(II)
//ES6
functionf(x,y,...a){
return(x+y)*a.length
}
f(1,2,"hello",true,7)===9
13.28VALORESPORDEFECTO(I)
//ES5
function(valor){
valor=valor||"foo";
}
13.29VALORESPORDEFECTO(I)
//ES6
function(valor="foo"){...};
13.30EXPORTARMÓDULOS
//ES6
//lib/math.js
exportfunctionsum(x,y){returnx+y}
exportfunctiondiv(x,y){returnx/y}
exportvarpi=3.141593
13.31IMPORTARMÓDULOS
//ES6
//someApp.js
import*asmathfrom"lib/math"
console.log("2π="+math.sum(math.pi,math.pi))
//otherApp.js
import{sum,pi}from"lib/math"
console.log("2π="+sum(pi,pi))
13.32GENERADORES
//ES6
function*soyUnGenerador(i){
yieldi+1;
yieldi+2;
yieldi+3;
}
vargen=soyUnGenerador(1);
console.log(gen.next());
//Object{value:2,done:false}
console.log(gen.next());
//Object{value:3,done:false}
console.log(gen.next());
//Object{value:4,done:false}
console.log(gen.next());
//Object{value:undefined,done:true}
13.33SET
//ES6
lets=newSet()
s.add("hello").add("goodbye").add("hello")
s.size===2
s.has("hello")===true
for(letkeyofs.values()){//insertionorder
console.log(key)
}
13.34MAP
//ES6
letm=newMap()
m.set("hello",42)
m.set(s,34)
m.get(s)===34
m.size===2
for(let[key,val]ofm.entries()){
console.log(key+"="+val)
}
13.35NUEVOSMÉTODOSENSTRING
//ES6
"hello".startsWith("ello",1)//true
"hello".endsWith("hell",4)//true
"hello".includes("ell")//true
"hello".includes("ell",1)//true
"hello".includes("ell",2)//false
13.36NUEVOSMÉTODOSENNUMBER
//ES6
Number.isNaN(42)===false
Number.isNaN(NaN)===true
Number.isSafeInteger(42)===true
Number.isSafeInteger(9007199254740992)===false
13.37PROXIES
//ES6
lettarget={
foo:"Welcome,foo"
}
letproxy=newProxy(target,{
get(receiver,name){
returnnameinreceiver?receiver[name]:`Hello,${name}`
}
})
proxy.foo==="Welcome,foo"
proxy.world==="Hello,world"
13.38INTERNACIONALIZATION(I)
//ES6
vari10nUSD=newIntl.NumberFormat("en-US",{style:"currency",currency:"USD
vari10nGBP=newIntl.NumberFormat("en-GB",{style:"currency",currency:"GBP
i10nUSD.format(100200300.40)==="$100,200,300.40"
i10nGBP.format(100200300.40)==="£100,200,300.40"
13.39INTERNACIONALIZATION(II)
//ES6
vari10nEN=newIntl.DateTimeFormat("en-US")
vari10nDE=newIntl.DateTimeFormat("de-DE")
i10nEN.format(newDate("2015-01-02"))==="1/2/2015"
i10nDE.format(newDate("2015-01-02"))==="2.1.2015"
13.40PROMESAS(I)
//ES6
varpromise=newPromise(function(resolve,reject){
vartodoCorrecto=true;//ofalsedependiendodecomohaido
if(todoCorrecto){
resolve("PromesaResuelta!");
}else{
reject("PromesaRechazada!");
}
});
13.41PROMESAS(II)
//ES6
//llamamoselmetodo'then'delapromesa
//con2callbacks(resolveyreject)
promise.then(function(result){
console.log(result);//"PromesaResuelta!"
},function(err){
console.log(err);//Error:"PromesaRechazada!"
});
13.42PROMESAS(III)
//ES6
//podemostambiénllamaral'then'conelcallback'resolve'
//yluegoal'catch'conelcallback'reject'
promise.then(function(result){
console.log(result);//"PromesaResuelta!"
}).catch(function(err){
console.log(err);//Error:"PromesaRechazada!"
});
13.43PROMESAS(IV)
//ES6
Promise.all([promesa1,promesa2]).then(function(results){
console.log(results);//cuandotodaslaspromesasterminen
}).catch(function(err){
console.log(err);//Error:"Errorenalgunapromesa!"
});
13.44PROMESAS(V)
//ES6
Promise.race([promesa1,promesa2]).then(function(firstResult){
console.log(firstResult);//cuandoterminelaprimera
}).catch(function(err){
console.log(err);//Error:"Errorenalgunapromesa!"
});
14ENLACES
14.1GENERAL(ES)
http://developer.mozilla.org/es/docs/Web/JavaScript/G
http://cevichejs.com/
http://www.arkaitzgarro.com/javascript/
http://www.etnassoft.com/category/javascript/
14.2GENERAL(EN)
http://www.javascriptkit.com/
http://javascript.info/
http://www.howtocreate.co.uk/tutorials/javascript/
14.3ORIENTACIÓNOBJETOS(ES)(I)
http://www.programania.net/diseno-desoftware/entendiendo-los-prototipos-en-javascript/
http://www.programania.net/diseno-desoftware/creacion-de-objetos-eficiente-enjavascript/
http://blog.amatiasq.com/2012/01/javascriptconceptos-basicos-herencia-por-prototipos/
14.4ORIENTACIÓNOBJETOS(ES)(II)
http://albertovilches.com/profundizando-enjavascript-parte-1-funciones-para-todo
http://albertovilches.com/profundizando-enjavascript-parte-2-objetos-prototipos-herencia-ynamespaces
http://www.arkaitzgarro.com/javascript/capitulo9.html
http://www.etnassoft.com/2011/04/15/conceptode-herencia-prototipica-en-javascript/
14.5ORIENTACIÓNOBJETOS(EN)
http://www.codeproject.com/Articles/687093/Understa
JavaScript-Object-Creation-Patterns
http://javascript.info/tutorial/object-oriented-programm
http://www.howtocreate.co.uk/tutorials/javascript/obje
14.6TÉCNICASAVANZADAS(ES)(I)
http://www.etnassoft.com/2011/03/14/funcionesautoejecutables-en-javascript/
http://www.etnassoft.com/2012/01/12/el-valor-de-thisjavascript-como-manejarlo-correctamente/
https://developer.mozilla.org/es/docs/Web/JavaScript/C
http://www.variablenotfound.com/2012/10/closures-en
javascript-entiendelos-de.html
14.7TÉCNICASAVANZADAS(ES)(II)
http://www.webanalyst.es/espacios-de-nombresen-javascript/
http://www.etnassoft.com/2011/04/11/el-patronde-modulo-en-javascript-en-profundidad/
http://www.etnassoft.com/2011/04/18/ampliandopatron-modulo-javascript-submodulos/
http://notasjs.blogspot.com.es/2012/04/el-patronmodulo-en-javascript.html
14.8DOM(ES)
http://cevichejs.com/3-dom-cssom#dom
http://www.arkaitzgarro.com/javascript/capitulo13.html
14.9DOM(EN)
http://www.javascriptkit.com/domref/
http://javascript.info/tutorial/dom
14.10FRAMEWORKS(ES)
https://carlosazaustre.es/blog/frameworks-de-javascrip
https://docs.google.com/drawings/d/1bhe9kxhhGvWU0LsB7LlJfMurP3DGCIuUOmqEOklzaQ/edit
http://www.lostiemposcambian.com/blog/javascript/ba
vs-angular-vs-ember/
http://blog.koalite.com/2015/06/grunt-o-gulp-que-uso/
14.11FRAMEWORKS(EN)
http://www.slideshare.net/deepusnath/javascript-fram
http://stackshare.io/stackups/backbone-vs-emberjs-vs
http://www.hongkiat.com/blog/gulp-vs-grunt/
https://mattdesl.svbtle.com/browserify-vs-webpack
http://hackhat.com/p/110/module-loader-webpack-vs-r
http://devzum.com/2014/02/10-best-node-js-mvc-fram
http://www.tivix.com/blog/nwjs-and-electronjs-web-tec
http://stackshare.io/stackups/phonegap-vs-ionic-vs-rea
https://developer.salesforce.com/page/Native,_HTML5
14.12EVENTOS(ES)
http://cevichejs.com/3-dom-cssom#eventos
http://www.arkaitzgarro.com/javascript/capitulo15.html
http://codexexempla.org/curso/curso_4_3_e.php
14.13EVENTOS(EN)
https://developer.mozilla.org/enUS/docs/Web/API/EventTarget
https://developer.mozilla.org/enUS/docs/Web/API/Event
http://dev.housetrip.com/2014/09/15/decouplingjavascript-apps-using-pub-sub-pattern/
https://stackoverflow.com/questions/5963669/whatsthe-difference-between-event-stoppropagation-andevent-preventdefault
14.14WEBSOCKETS(ES)
http://www.html5rocks.com/es/tutorials/websockets/ba
https://carlosazaustre.es/blog/websockets-como-utiliza
socket-io-en-tu-aplicacion-web/
14.15WEBSOCKETS(EN)
https://davidwalsh.name/websocket
http://code.tutsplus.com/tutorials/start-usinghtml5-websockets-today--net-13270
14.16AJAX,JSON,REST(ES)
https://fernetjs.com/2012/09/jsonp-cors-y-como-los-so
desde-nodejs/
http://blog.koalite.com/2012/03/sopa-de-siglas-ajax-jso
cors/
https://eamodeorubio.wordpress.com/category/webse
https://eamodeorubio.wordpress.com/category/webse
14.17ES6(ES)
http://rlbisbe.net/2014/08/26/articulo-invitadoecmascript-6-y-la-nueva-era-de-javascript-porckgrafico/
http://carlosazaustre.es/blog/ecmascript-6-el-nuevoestandar-de-javascript/
http://asanzdiego.blogspot.com.es/2015/06/principiossolid-con-ecmascript-6-el-nuevo-estandar-dejavascript.html
http://www.cristalab.com/tutoriales/uso-de-modulosen-javascript-con-ecmascript-6-c114342l/
https://burabure.github.io/tut-ES6-promisesgenerators/
14.18ES6(EN)
http://es6-features.org/
http://kangax.github.io/compat-table/es5/
http://www.2ality.com/2015/11/sequentialexecution.html
http://www.html5rocks.com/en/tutorials/es6/promises/
http://www.datchley.name/es6-promises/
Descargar