JavaScript per a desenvolupadors de C#
Edin Kapić
JavaScript
Edin Kapić
C#!=
Qui sóc?
SUG.CATSharePoint User Group Catalunya
Edin KapićKey Consultant (SharePoint)[email protected]
@ekapic
JavaScript: “With or Without You”
Brendan Eich“El pare de la
criatura”
Com hem arribat fins aquí?
1995Netscape Navigator
2.0Mocha/LiveScript
1996Internet Explorer
3.0JScript
1997ECMAScript
1999XMLHttpRequest(OWA Exchange
2000)
2005Jesse James
GarrettAJAX
2006John Resig
jQuery
2009PhoneGap
2010Node.js
2011Windows 8
2012SharePoint 2013
TypeScript
TypeScript
Hem de donar el salt
JsFiddle
Firebug / IE Dev Tools
JSLint
Les einesFirebugLite
JavaScript és bo ...• Llenguatge dinàmic• Notació literal potent• “Loose-typed”
• “JS is Lisp in C Clothing” (Douglas Crockford)
http://bit.ly/Qn0qLi
... però té coses dolentes• Variables globals implícites• Variable hoisting• Function hoisting• Prototype Leaking• ==
'' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // falsefalse == null // false null == undefined // true ' \t\r\n ' == 0 // true
JavaScript != C#
• C#– Talla pa– Té mecanismes de
seguretat– És complex
• JavaScript– Talla pa– Et pots fer mal– Es un tros de metall
amb un mànec
Bo en C#, dolent en JS• La sintaxi semblant ens pot portar a
fer coses que a C# són bones pràctiques
• Però poden tenir conseqüències greus a JS
• “If it walks like a duck...”
JS != C# 1: Tipus de dadesSimples• Number• String• Boolean• Undefined• Null
Complexos• Object• Array• Function• RegEx• Date
JS != C# 2: Variables globals
• Tota variable no assignada a un objecte, s’assigna a window
• var a = 1;• window.a = 1;
http://jsfiddle.net/wQDwN/
JS != C# 3: “Variable Hoisting”
• Només dos nivells: global i funció– { } no crea àmbit de variable (com a
C#)
• La variable declarada puja fins el principi de la funció dins la qual està declarada– /*.....*/ var a = 1;– var a; /*.....*/ a = 1;
http://jsfiddle.net/NE2Km/3/
Recomanació• Ser conscient dels tipus de dades• No contaminar window• Declarar variables a dalt de tot (fer
el hoisting explícit)
JS != C# 4: Wrappers• JS estil C#
var myVar = new Object();var myArr = new Array();
• JS estil purvar myVar = {};var myArr = [];
Recomanació• No fer servir wrappers
innecessàriament• Aprendre la notació literal d’objectes
de JS
JS != C# 5: Truthy / FalseyValors que donen true
• "0"• "false"• Objectes buits• Tota la resta
Valors que donen false
• false• 0• ""• null• undefined• NaN
Recomanació• Simplifiquem els condicionals
if(myVar != "" || myVar != undefined)if(myVar)
• Inicialitzem els valors per defecteif(myVar == "") { myVar = "Hola"; }myVar = myVar || "hola";
JS != C# 6: L’operador ==• Comparació
if(false == 0) // trueif(false === 0) // false
• L’operador == intenta convertir els valors i gairebé segur que no és el que volem
Comparació “indeterminista”(false == 0); // true (false == ""); // true (0 == ""); // true (null == false); // false(null == null); // true(undefined == undefined); // true(undefined == null); // true(NaN == null); // false(NaN == NaN); // false
Recomanació• Fem servir els operadors === i !==
per defecte• No fan conversió de valors• Es comporten com els operadors
“habituals” == i != de C#
JS != C# 7: Altres “perles”• parseInt() • L’operador + http://jsfiddle.net/tbMX2
/• NaN http://jsfiddle.net/vVgB9/ • “Prototype Leak”
Funcions
Funcions de JavaScript• Són objectes, per tant s’hi
poden afegir propietats• Es poden passar com a
paràmetres a altres funcions
• Hi ha dues maneres de declarar funcions
Manera 1: Declaracions• La declaració de la funció es fa així
function foo() { /* .... */ }
• La funció declarada fa “hoisting” i és disponible a tot el codi JS, independentment de l’ordre
http://jsfiddle.net/TQ6LG/
Manera 2: Expressions• També podem assignar la funció a una
variable mitjançant una expressió:var foo = function () { /* ... */ };
• En aquest cas no hi ha “hoisting”• Podem pensar que una declaració és
realment una expressió posada a dalt de tot
http://jsfiddle.net/NrQhM/
Equivalències• function foo() { /* .... */ }• var foo = function () { /* ... */ };• var foo = function foo () { /* ... */ };• var foo = function bar () { /* ... */ };
• Les dues últimes es fan servir per a funcions recursives
• Les expressions fan explícita la declaració
Codi d’un sol ús• Podem assignar una funció
anònimament i no recollir-la• Útil per a executar un codi privat i
d’una sola vegada
• (function () { /* ... */ })();
http://jsfiddle.net/YAe9S/1/
Anidament de funcions• Les funcions són objectes i poden
contenir altres funcions
var foo = function() { function bar() { /* ... */ } return bar();};foo();
http://jsfiddle.net/XUswD/
Tancaments (Closures)• El tancament és una manera d’associar
la funció amb els seus paràmetres d’entrada– És el manteniment de les variables locals
desprès de que la funció hagi retornatvar bind = function(x) { return function(y) { return x + y; };}var plus5 = bind(5); alert(plus5(3));
http://jsfiddle.net/xWAm4/
Recomanacions• Dedicar temps per a jugar amb les
funcions en JS és imprescindible– Hi ha molts exemples que es poden
provar amb JsFiddle
• Comprendre els tancaments és important per a entendre els event handlers i encapsulament
JavaScript al segle XXI
Anem tirant?
O estem al dia?
Regla #1: Unobtrusive JavaScript
• El codi JS s’ha d’afegir sense impactar el HTML de la pàgina<input type="text" name="date“ onchange="validateDate()" />
window.onload = function() { document.getElementById('date').onchange = validateDate;};
Regla #2: Modularitat• El nostre codi JS no pot
col·lisionar amb qualsevol altre codi JS present
• Encapsulem el nostre codi en namespaces
• Fem servir try/catch
Mètodes d’encapsulament• Cap (objecte window)• Tot privat (funció anònima auto-
executada)
• Tot públic (objecte literal)• Barreja public/privat (Revealing
Module)
Objecte literalvar car = { status: "off", start: function() { this.status = "on"; }, getStatus: function() { return "the car is " + this.status; }};car.start();alert(car.getStatus());
http://jsfiddle.net/DY2Zw/
Revealing Modulevar car = (function() { var pubCar = {}, var innerStatus = "off"; pubCar.start = function() { innerStatus = "on"; } pubCar.status = function() { return "the car is “ + innerStatus; } return pubCar;}());car.start();alert(car.status());
http://jsfiddle.net/AUzNT/
Recomanacions• Fer servir Revealing Module per a tenir
encapsulament totalment controlat per nosaltres
• Aïllar-nos d’altres llibreries http://jsfiddle.net/uKuLw/
• Fer servir objecte literal per a fer objectes senzills (p.ex. DTOs)– La sintaxi és diferent
Regla #3: Abstracció• Cal abstreure’s dels detalls del
navegador concret
• Existeixen llibreries que ens unifiquen les diferències: jQuery, AmplifyJS, Modernizr
Llibreries que cal conèixer• MVVM: KnockoutJS• Plantilles: JsRender• Notificacions: SignalR, Toastr• Tests unitaris: QUnitJS• BDD: Jasmine• IoC/DI: Inject, RequireJS
KnockoutJS• Possibilita al patró MVVM
(Model-View-ViewModel)
http://knockoutjs.com/Demo: http://knockoutjs.com/examples/helloWorld.html
• Automatitza el binding bidireccional entre el viewmodel (JS) i la vista (HTML)
JsRender• Permet fer “plantilles”
d’elements HTML i enllaçar-les amb dades
https://github.com/BorisMoore/jsrender
Demo: http://borismoore.github.com/jsrender/demos/step-by-step/05_for-tag.html
SignalR• Notificacions asíncrones de
servidor a client i vice-versa• Útil per a notificacions de
sistema a l’usuari• http://signalr.net
• Demo: http://zooplet.com/tictactoe/
Toastr• Notificacions tipus “torrada”
• https://github.com/CodeSeven/toastr• Demo: http://CodeSeven.github.com/toastr
QUnitJS• Proves unitàries per al
codi de JavaScript• Executable dins el
navegador
http://qunitjs.com/
Demo: http://jsfiddle.net/booyaa/kdEtk/
Jasmine• Proves funcionals amb
JavaScript• Descriuen el resultat
esperat i poden combinar-se per a formar casos d’ús
• https://github.com/pivotal/jasmine• Demo: http://pivotal.github.com/jasmine/
Inject / RequireJS• Gestió de dependències entre
components JS• https://github.com/linkedin/inject• Demo: http://bit.ly/wu2Pe1
• Alternativa: RequireJS• http://requirejs.org
Microsoft TypeScript• És un llenguatge basat en
JavaScript• Afegeix la comprovació en temps
de compilació de referències, tipus, classes i interfícies
• (Trans)compila a JavaScript “pur”• Disponible per a VS2012• http://www.typescriptlang.org/
Resum
Recomanacions• Invertir temps en aprendre els
principis de JS i experimentar amb els exemples
• Repassar el codi existent amb JSLint• Tenir en compte les llibreries de JS
com a factor arquitectònic a les aplicacions
• JS està aquí per a quedar-s’hi
Bibliografia• Douglas Crockford “JavaScript: The
Good Parts” (O’Reilly)• Addy Osmani “JavaScript Design
Patterns” http://bit.ly/bMyoQ9
• http://jsbooks.revolunet.com/
Top Related