JavaScript per a desenvolupadors de C#

Report
JavaScript para
desarrolladores de C#
Edin Kapić
JavaScript
Edin Kapić
!= C#
JavaScript: “With or Without You”
Brendan Eich
“El padre de la criatura”
¿Cómo llegamos hasta aquí?
1995
Netscape Navigator 2.0
Mocha/LiveScript
1996
Internet Explorer 3.0
JScript
1997
ECMAScript
1999
XMLHttpRequest
(OWA Exchange
2000)
2005
Jesse James Garrett
AJAX
2006
John Resig
jQuery
TypeScript
2009
PhoneGap
2010
Node.js
2011
Windows 8
2012
SharePoint 2013
TypeScript
Hay que saltar de una vez
Firebug / IE Dev Tools
JSLint
JSHint
JsFiddle
Las herramientas
Firebug
Lite
JavaScript es bueno ...
• Lenguaje dinámico
• Notación literal potente
• “Loose-typed”
• “JS is Lisp in C Clothing” (Douglas Crockford)
http://bit.ly/Qn0qLi
... pero tiene cosas malas
•
•
•
•
•
Variables globales implícitas
Variable hoisting
'' == '0'
0 == ''
Function hoisting
0 == '0'
false == 'false'
false == '0'
Prototype Leaking
false == undefined
false == null
==
null == undefined
' \t\r\n ' == 0
//
//
//
//
//
//
//
//
//
false
true
true
false
true
false
false
true
true
JavaScript != C#
• C#
– Corta el pan
– Tiene mecanismos de
seguridad
– Es complejo
• JavaScript
– Corta el pan
– Te puedes hacer daño
– Es un trozo de metal
con un mango
Bueno en C#, malo en JS
• La sintaxis parecida nos puede llevar a hacer
lo que en C# son buenas prácticas
• ...pero en JS pueden tener consecuencias
graves
• “If it walks like a duck...”
JS != C# 1: Tipos de datos
Simples
• Number
• String
• Boolean
• Undefined
• Null
Complejos
• Object
• Array
• Function
• RegExp
• Date
JS != C# 2: Variables globales
• Toda variable no asignada a un objeto,
se asigna a window
• var a = 1;
• window.a = 1;
http://jsfiddle.net/wQDwN/
JS != C# 3: “Variable Hoisting”
• Sólo dos niveles: global i función
– { } no crea ámbito de variable (como C#)
• La variable declarada sube hasta el inicio
de la función en la que está declarada
– /*.....*/ var a = 1;
– var a; /*.....*/ a = 1;
http://jsfiddle.net/NE2Km/3/
Recomendación
• Ser consciente de los tipos de datos
• No contaminar window
• Declarar variables lo más arriba possible
(hacer hoisting explícito)
Test
var imAGlobal = true;
function globalGrabber() {
imAGlobal = false;
return imAGlobal;
}
console.log(imAGlobal);
console.log(globalGrabber());
console.log(imAGlobal);
// true o false?
Test
var imAGlobal = true;
function globalGrabber() {
var imAGlobal = false;
return imAGlobal;
}
console.log(imAGlobal);
console.log(globalGrabber());
console.log(imAGlobal);
// true o false?
http://jsfiddle.net/JxESg/
JS != C# 4: this
• this apunta al objeto contenedor de la función
en la que está (en ejecución) y es modificable
console.log(this); // window
var myFunction = function() {
console.log(this);
}
myFunction();
// window
http://jsfiddle.net/UsCtz/ y http://jsfiddle.net/8tBEM/
JS != C# 5: Wrappers
• JS estilo C#
var myVar = new Object();
var myArr = new Array();
• JS estilo puro
var myVar = {};
var myArr = [];
Recomendación
• No usar wrappers innecesariamente
• Aprender la notación literal de objetos de JS
Test
var a = new Object();
a.nombre = 'Edin';
console.log(a.nombre);
Test
var a = {
nombre: 'Edin'
};
console.log(a.nombre);
Test
var a = function()
{
this.nombre = 'Edin';
return this;
}();
console.log(a.nombre);
Test
var a = function()
{
this.nombre = 'Edin';
return this;
}();
console.log(a.document.URL);
Test
var a = function()
{
var obj = {};
obj.nombre = 'Edin';
return obj;
}();
console.log(a.document.URL);
JS != C# 6: Truthy / Falsey
Valores que dan true
Valores que dan false
•
•
•
•
•
•
•
•
•
•
"0"
"false"
Objetos vacíos
Todos los demás
false
0
""
null
undefined
NaN
Recomendación
• Simplificar los condicionales
if(myVar != "" || myVar != undefined)
if(myVar)
• Inicializar los valores por defecto
if(myVar == "") { myVar = "Hola"; }
myVar = myVar || "hola";
JS != C# 7: Operador ==
• Comparación
if(false == 0)
if(false === 0)
// true
// false
• El operador == intenta convertir los valores y
casi siempre es algo que no queremos
Comparación “indeterminista”
(false == 0);
(false == "");
(0 == "");
(null == false);
(null == null);
(undefined == undefined);
(undefined == null);
(NaN == null);
(NaN == NaN);
//
//
//
//
//
//
//
//
//
true
true
true
false
true
true
true
false
false
Recomendación
• Usar los operadores === i !== por defecto
• No hacen la conversión de valores
• Se comportan como los operadores
“habituales” == y != de C#
JS != C# 8: Otras “perlas”
•
•
•
•
•
parseInt()
Operador + http://jsfiddle.net/tbMX2/
NaN http://jsfiddle.net/vVgB9/
“Prototype Leak”
Inserción de ;
Funciones
Funciones de JavaScript
• Son objetos, por tanto se les
pueden agregar propiedades
• Se pueden pasar como
parámetros a otras funciones
• Hay dos maneras de declarar
funciones
Manera 1: Declaración
• La declaración de la función se
hace con
function foo() { /* .... */ }
• La función declarada hace “hoisting” y està
disponible en todo el código JS,
independientemente del orden de ejecución
http://jsfiddle.net/TQ6LG/
Manera 2: Expresión
• También podemos asignar la función a
una variable mediante una expresión:
var foo = function () { /* ... */ };
• En este caso no hay “hoisting”
• Podemos pensar que una declaración es
realmente una expresión puesta al principio
http://jsfiddle.net/NrQhM/
Equivalencias
•
•
•
•
function foo() { /* .... */ }
var foo = function () { /* ... */ };
var foo = function foo () { /* ... */ };
var foo = function bar () { /* ... */ };
• Las dos últimas se usan para funciones recursivas
• Las expresiones hacen explícita la declaración
Código de un solo uso (IIFE)
• Podemos asignar una función anónimamente y
no recogerla como resultado
• Útil para ejecutar un código privado y de una
sola vez
• (function () { /* ... */ })();
http://jsfiddle.net/YAe9S/1/
Anidamiento de funciones
• Las funcions son objetos y pueden contener
otras funciones
var foo = function() {
function bar() {
/* ... */
}
return bar();
};
foo();
http://jsfiddle.net/XUswD/
Cierres (Closures)
• El cierre es una manera de asociar la función
con sus parámetros de entrada
– Es el mantenimiento de las variables locales
después de que la función haya acabado
var bind = function(x) {
return function(y) { return x + y; };
}
var plus5 = bind(5);
alert(plus5(3));
http://jsfiddle.net/xWAm4/
Recomendaciones
• Dedicar tiempo para jugar con las funciones
en JS es imprescindible
– Hay muchos ejemplos que se pueden probar
con JsFiddle
• Comprender los cierres es importante para
entender los event handlers y
encapsulamiento (http://jsfiddle.net/GBfPf/)
JavaScript en el siglo XXI
¿Vamos tirando?
¿O estamos al día?
Regla #1: Unobtrusive JavaScript
• El JS se tieen que añadir sin impactar el
HTML de la página
<input type="text" name="date“
onchange="validateDate()" />
window.onload = function() {
document.getElementById('date').onchange
= validateDate;
};
Regla #2: Modularidad
• No colisionar con otros JS
presentes (es decir,
“comportarnos bien”)
• Encapsulemos nuestro
código en namespaces
• Usemos try/catch
Métodos de encapsulamiento
• Ninguno (objeto window)
• Todo privado (función anónima autoejecutada)
• Todo público (objeto literal)
• Mezcla público/privado (Revealing Module)
Objeto literal
var car = {
status: "off",
start: function() {
this.status = "on";
},
getStatus: function() {
return "the car is " + this.status;
}
};
car.start();
http://jsfiddle.net/DY2Zw/
alert(car.getStatus());
Revealing Module
var 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/
Recomendaciones
• Usar Revealing Module para tenir el
encapsulamiento totalmente controlado por
nosotros
• Aislarnos de otras librerías
http://jsfiddle.net/uKuLw/
• Usar objetos literales para objetos sencillos (p.ej.
DTOs)
– La sintaxis es diferente
Regla #3: Abstracción
• Nos abstraeremos de los detalles del
navegador concreto
• Existen librerías que
unifican y abstraen
las diferencias:
jQuery, AmplifyJS,
Modernizr
Microsoft TypeScript
• Es un lenguaje basado en JavaScript
• Añade la comprobación en tiempo
de compilación de referencias, tipos,
clases e interfaces
• (Trans)compila a JavaScript “puro”
• Disponible para VS2012
• http://www.typescriptlang.org/
Resumen
Recomendaciones
• Invertir tiempo en aprender los principios de
JS y experimentar con los ejemplos
• Repasar el código existente con JSHint
• Tener en cuenta las librerías de JS como
factor arquitectónico en las aplicaciones
• JS está aquí para quedarse
Bibliografia
• Douglas Crockford “JavaScript: The Good
Parts” (O’Reilly)
• Addy Osmani “JavaScript Design Patterns”
http://bit.ly/bMyoQ9
• http://jsbooks.revolunet.com/
• http://superherojs.com

similar documents