JavaScript para desarrolladores de C# Edin Kapić

Preview:

Citation preview

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í?

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

Hay que saltar de una vez

JsFiddle

Firebug / IE Dev Tools

JSLintJSHint

Las herramientasFirebugLite

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• 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#– 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 datosSimples• 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)

Testvar imAGlobal = true; function globalGrabber() { imAGlobal = false; return imAGlobal;} console.log(imAGlobal); console.log(globalGrabber()); console.log(imAGlobal); // true o false?

Testvar 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); // windowvar 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 purovar myVar = {};var myArr = [];

Recomendación• No usar wrappers innecesariamente• Aprender la notación literal de

objetos de JS

Testvar a = new Object();a.nombre = 'Edin';console.log(a.nombre);

Testvar a = { nombre: 'Edin'};console.log(a.nombre);

Testvar a = function(){ this.nombre = 'Edin'; return this;}();console.log(a.nombre);

Testvar a = function(){ this.nombre = 'Edin'; return this;}();console.log(a.document.URL);

Testvar a = function(){ var obj = {}; obj.nombre = 'Edin'; return obj;}();console.log(a.document.URL);

JS != C# 6: Truthy / FalseyValores que dan true

• "0"• "false"• Objetos vacíos• Todos los demás

Valores que dan false

• false• 0• ""• null• undefined• NaN

Recomendación• Simplificar los condicionales

if(myVar != "" || myVar != undefined)if(myVar)

• Inicializar los valores por defectoif(myVar == "") { myVar = "Hola"; }myVar = myVar || "hola";

JS != C# 7: Operador ==• Comparación

if(false == 0) // trueif(false === 0) // false

• El operador == intenta convertir los valores y casi siempre es algo que no queremos

Comparación “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

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 confunction 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 auto-

ejecutada)

• Todo público (objeto literal)• Mezcla público/privado (Revealing

Module)

Objeto 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/

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