JavaScript pour les développeurs .NET

Preview:

DESCRIPTION

L'idée est de faire un point sur JavaScript, ses origines et son actualité, vu de la perspective d'un développeur Microsoft. Cette présentation est essentiellement destinée aux développeurs .NET qui auraient le sentiment d'avoir un peu lâché JavaScript, et qui voudraient se remettre dans le bain.

Citation preview

2

JavaScriptpour les développeurs .NET

Thomas ContéMicrosoft

3

Agenda

Brève histoire de JavaScriptJavaScript dans IEJavaScript: le langageECMAScript5Frameworks & librairiesJavaScript côté serveur

Node.JS & Windows Azure

4

Piqûre de rappel

5

Brève histoire de JavaScript

Netscape & Brendan EichMocha, LiveScript, JavaScript

MicrosoftJScript : IE3, 1996Même langage, nom différent

ECMAScript Première édition: Juin 1997AJAX

XMLHTTP : IE5, 1999

JSON "Découvert" par Crockford en 2001-2002jQuery & John Resig: 2006Les temps modernes?

6

Le chemin parcouru…<a href="index.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('img1978','','bar_nav_on_01.gif',1)"> <img name="img1978" border="0" src="bar_nav_no_01.gif" width="24" height="88"></a>

...

<script language="JavaScript">function MM_swapImage() { //v3.0var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}}</script>

Depuis le JavaScript généré par DreamWeaver…

Jusqu’aux applications modernes les plus complexes: Office Web Apps, Bing Maps, Gmail

(443K LOC), etc.

7

JavaScript, l’Assembleur du Web?

Scott Hanselman : JavaScript, l'Assembleur du Web? JavaScript est universellement déployéIl est rapide, et devient de plus en plus rapideJavaScript est le langage "de bas niveau" du WebVous pouvez le fignoler à la main, ou le générer à partir d'un langage de plus haut niveau (CoffeScript, Script#, etc.)

8

JavaScript dansInternet Explorer

9

Chakra

Chakra est le nouveau moteur JavaScript dans IE9 et +

Performances dignes d’un « navigateur moderne »

Benchmarks + scénarios « réels »

Support JavaScript dernier criECMAScript 5

10

Performances

La course aux benchmarksE.g. WebKit SunSpiderNécessaire, mais pas suffisant!Il faut optimiser pour la « vraie vie »

11

JSMeterhttp://research.microsoft.com/en-us/projects/jsmeter/

\ie\jscript\*.cpp

Instrumentation de Internet Explorer 8

custom jscript.dll

custom trace fileswebsite visits

Analyseurs

custom trace files0%

10%20%30%40%50%60%70%80%90%

100%

Constant

Other Str Ops

Concat Op

12

« JavaScript & Metaperformance »

Présentation de Douglas Crockford à Velocity 2011Dans le même esprit que MS Research, Douglas Crockford a utilisé sa propre application JSLint pour comparer les interpréteurs

13

Crockford « JSLint benchmark »

14

Architecture de Chakra

16

Developer Tools

Console JavaScript• console.log()• Permet de tester des commandes

Débogueur• Breakpoints• Inspection• Call stack• Dé-minification

Profiler

17

DémoDeveloper Tools

18

JavaScript: le langage

19

JavaScript !== C#

Règles de portée (scoping)Utilisation de Patterns type Module pour éviter de polluer la portée globale

« traction » des variables et fonctions (hoisting)Les valeurs « presque fausses » (false-y values)Opérateurs de comparaisonDéclaration des tableaux & objetsUtilisation du for … in (indice: pas comme en C#)Utilisation des Closures…

scopingfunction mange() {// Code incorrect!    var quoi = "un mars",         jaiFaim = true;        if ( jaiFaim ) {        // En C#, timeToWait n’est accessible que dans ce if; pas en JavaScript!        var timeToWait = 10;                console.log( "Attendre " + timeToWait + " minutes" );                mache();    }        function mache() {        var comment = "ma bouche";                // Cette fonction a accès à timeToWait car elle est en fait dans        // le périmètre de la fonction eat()        console.log( "Après " + timeToWait +             " minutes, je mange " + quoi + " avec " + comment );    }}

mange();// Attendre 10 minutes// Après 10 minutes, je mange un mars avec ma bouche

Awful

Part

scoping// Code correctfunction mange() {    var quoi = "un mars",         jaiFaim = true,        timeToWait, bodyPart;        if ( jaiFaim ) {        timeToWait = 10;                console.log( "Attendre " + timeToWait + " minutes" );                mache();    }        function mache() {        var comment = "ma bouche";                console.log( "Après " + timeToWait +             " minutes, je mange " + quoi +             " avec " + comment );    }}

mange();// Attendre 10 minutes// Après 10 minutes, je mange un mars avec ma bouche

hoistingconsole.log( someVariable ); //undefinedvar someVariable = 42; //Global variableconsole.log( someVariable ); // 42

function doSomething() {    console.log( someVariable ); // undefined    //Pourquoi undefined??

    someVariable = 1    console.log( someVariable ); // 1        console.log( window.someVariable ); // 42    //Pourquoi 42?        if ( false ) {        var someVariable = 0;    }}

doSomething();

hoistingvar someVariable = undefined;console.log( someVariable ); //undefinedsomeVariable = 42; //Global variableconsole.log( someVariable ); // 42

function doSomething() {    //Le hoisting amène le var en haut de la fonction,     //et l’initialise à undefined !    var someVariable = undefined;    console.log( someVariable ); // undefined

    someVariable = 1    console.log( someVariable ); // 1    //Cette ligne de code n’accède pas à la var globale,    //mais à la locale qui a été « tractée »

    console.log( window.someVariable ); // 42

    if ( false ) {        someVariable = 0;    }}

doSomething();

false-y values

falsenullundefined"" (empty string)0NaN (not a number)

Awful

Part

comparaisons

console.log( 0 == '' ); //true console.log( 0 == '0' ); //true console.log( false == '0' ); //true console.log( null == undefined ); //true console.log( 0 == ' \t\r\n ' ); //true

comparaisons

console.log( 0 === '' ); //false console.log( 0 === '0' ); //false console.log( false === '0' ); //false console.log( null === undefined ); //false console.log( 0 === ' \t\r\n ' ); //false

tableaux & objets

var person = {firstName: "Thomas",lastName: "Conté",sayFullName: function() {

console.log(this.firstName+" "+

this.lastName );}

},keys = ["123", "676", "242", "4e3"];

objets & prototypes

function Car(model, year, miles) {   this.model = model;   this.year  = year;   this.miles = miles;} /* On utilise Object.prototype.newMethod et pas Object.prototype sinon l'on redéfinit le prototype!*/Car.prototype.toString = function() {        return this.model + " has done " +        this.miles + " miles";};  var civic = new Car("Honda Civic", 2009, 20000);var mondeo = new Car("Ford Mondeo", 2010, 5000); console.log(civic.toString());

for … in

var myArray = [], name;myArray[5] = "test";console.log( myArray.length ); //6

Array.prototype.someVariable = "pourquoi?";for ( name in myArray ) {    console.log( name, myArray[name] );     //Outputs...     //   5, test    //   someVariable, pourquoi ?}

var myArray = [], name;myArray[5] = "test";console.log( myArray.length ); //6

for ( var i = 0, length = myArray.length; i < length; i++ ) {    console.log( i, myArray[i] );     //Outputs...    //   0, undefined    //   1, undefined    //   2, undefined    //   3, undefined    //   4, undefined    //   5, test }

for … in

for … invar Person = function( firstName, lastName ) {  this.firstName = firstName;  this.lastName = lastName;  return this;};

Person.prototype = {  isMarried : false,  hasKids: false};

var john = new Person( "John", "Smith" ),  linda = new Person( "Linda", "Davis" ),  name;

john.isMarried = true;

console.log( "sans vérifier hasOwnProperty" );for ( name in john ) {  console.log( name + ": " + john[name] );   //Outputs  //  firstName: John   //  lastName: Smith  //  isMarried: true  //  hasKids: false}

console.log( "en vérifiant hasOwnProperty" );for ( name in linda ) {  if ( linda.hasOwnProperty(name) ) {    console.log( name + ": " + linda[name] );     //Outputs    //  firstName: Linda    //  lastName: Davis  }}

closures/* “Une closure est un type d'objet particulier qui combine deux éléments: une fonction, et l'environnement dans lequel cette fonction a été créée. L'environnement contient toutes les variables locales qui étaient dans le périmètre au moment de la création de la closure.” -- https://developer.mozilla.org/en/JavaScript/Guide/Closures */

function makeAdder( x ) {    return function( y ) {        return x + y;    };}

var add5 = makeAdder( 5 );var add10 = makeAdder( 10 );

console.log( add5(2) ); // 7console.log( add10(2) ); // 12

closures

for (var i = 0; i < 10; i++) {  document.getElementById('box' + i).onclick = function() {    alert('You clicked on box #' + i);  };}

pas marche!

for (var i = 0; i < 10; i++) {  document.getElementById('box'+i).onclick = (function(index){    return function() {      alert('You clicked on box #' + index);    };  })(i);}

marche!

module

var testModule = (function(){    var counter = 0;    return {        incrementCounter: function() {            return counter++;        },        resetCounter: function() {            console.log('counter was:' + counter);            counter = 0        }    }})(); /*test*/testModule.incrementCounter();testModule.resetCounter();

35

ECMAScript 5

36

Historique

37

Les apports d’ECMAScript 5

Énormément de « petits » changements pour rendre le langage plus cohérent« strict mode »

La plus importante nouveauté d’après CrockfordSupporté à partir de IE10

Modifications de la syntaxeJSONNouvelles méthodes: tableaux, dates…Modèle objet amélioré

Object.create, Object.keys …Getters & SettersMeta Object API

38

Strict Mode

Activé en ajoutant la chaîne magique:‘use strict’;Ignorée par les précédents interpréteursPérimètre fichier ou fonction (recommandé)

Plus de variables globales implicitesthis n’est plus relié au scope global dans un appel de fonction plus de pollution accidentelleEt bien d’autres mesures de sécurité

Recommandation: utiliser Strict Mode par défaut dès aujourd’hui

39

DémoECMAScript 5

40

Frameworks

41

Script#

Projet de Nikhil Kothari, aujourd'hui Partner Engineer chez Microsoft: http://projects.nikhilk.net/ScriptSharp Utilisé en interne par Microsoft

Office Web Applications / SharePoint Office Web ServicesBing : Maps, MobileWindows Live

Script# permet de compiler du C# en JavaScriptOn gagne la productivité des outils .NET, Visual StudioParticulièrement intéressant sur de grosses applications

Focalisé sur la production d’applications JavaScript optimales (plus que sur le portage d’applications .NET)

42

Knockout.JS

Projet de Steve Sanderdon, PM Web Tools chez Microsoft

http://knockoutjs.com/

Permet d’utiliser le pattern MVVM pour développer des interfaces utilisateur HTML / JavaScriptImplémente le pattern Observable

Binding bi-directionnel

Fournit un système de templating permettant de générer l’interface à partir du ViewModel

Exemples: http://knockoutjs.com/examples/

43

RxJS

Projet mené par l'équipe Rx chez Microsofthttp://msdn.microsoft.com/en-us/data/gg577609

Framework d’Event Processing, existe aussi pour .NET

Particulièrement adapté à la nature asynchrone de JavaScript

Basé sur deux notions principales:Observable SequencesObservers

Sources de Séquences : Timers, DOM, AJAX, … ou customProjections : .Select()Composition: .Throttle(), .DistinctUntilChanged(), …

45

JavaScript sur le serveur

46

Node.JS

Node.JS est développé par Ryan Dahl chez JoyentC’est un framework permettant de développer des services haute performances sur un modèle asynchroneL’idée étant que le modèle asynchrone est plus performant et plus efficace que le classique modèle multithreadé quand on a beaucoup d’entrées-sorties à gérer

Semblable dans le principe à l’Async CTP

JavaScript choisi car particulièrement adapté au développement asynchrone grâce à ses forts aspects fonctionnelsLe framework intègre le protocole HTTP en standard ainsi qu’une librairie système entièrement asynchrone

Hello Nodevar http = require('http'),  mysql = (new (require('mysql').Client)({user: 'root'}));

mysql.connect();mysql.query('use castle;');

http.createServer(function (req, res) {  res.writeHead(200, {'Content-Type': 'text/json'}); mysql.query('select * from dragons', function (e, d) {   if (e) {      res.end('ERROR'); } else { res.end(JSON.stringify(d)); } });}).listen(8124, '127.0.0.1');console.log('Server running at http://127.0.0.1:8124/');

48

Node.JS dans Windows Azure

Microsoft aide officiellement Ryan Dahl à porter Node.JS sur WindowsNode est constitué d’un seul exécutable, node.exe, donc très simple à inclure dans un Worker Role

49

DémoNode.JS sur Windows Azure

50

Conclusion

JavaScript est aujourd’hui l’un des langages de programmation les plus populairesSes performances en font un environnement d’exécution de premier ordre, dans le navigateur et même sur le serveurMicrosoft investit pour faire de JavaScript un langage de premier ordre sur sa plateforme:

Performances: IE9, IE10Respect des standards: ECMAScript 5Outils de développement: F12, Dev11Frameworks

… et plus encore à venir!

51

Brendan Eich, CapitolJS : http://www.slideshare.net/BrendanEich/capitol-js

52

Ressources!

JavaScript PatternsStoyan Stefanov

Eloquent JavaScriptMarijn Haverbeke

Essential JavaScript PatternsAddy Osmani

JavaScript: the Good PartsDouglas Crockford

ECMA-262, Edition 5ECMA International

Recommended