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/