JavaScript, langage mal aimé ?

  1. Historique
  2. Particularités
  3. Bonnes pratiques
  4. Évolutions à venir

Presenter Notes

Historique

  • Les origines (~ 1995)
  • Avènement d'Ajax (~ 2005)
  • JavaScript comme plateforme applicative (depuis 2010)

Presenter Notes

Les origines

  • Langage apparu en 1995 dans Netscape 2.0

  • Créé en 10 jours par Brendan Eich

  • Très vite adopté en interne au sein de Netscape
  • Utilisé surtout pour ajouter des effets visuels à des pages web

Presenter Notes

Avènement d'Ajax

  • Créé par Microsoft en 1999

  • Asynchronous JavaScript + XML : permet de faire des requêtes HTTP en JavaScript
  • Google démontre les possibilités en 2005 avec Gmail et Google Maps

  • Apparition des premières bibliothèques de développement

    • Prototype en 2005 créé sous l'impulsion de Ruby on Rails
    • jQuery en 2006

Presenter Notes

JS comme plateforme applicative

  • Applications web de type SPA (single-page applications) : IHM riche, navigation programmée en JavaScript
  • Prolifération de bibliothèques et de frameworks pour développer des applications complexes
    • AngularJS (2009)
    • Backbone.js (2010)
  • Applications mobiles multi-plateformes
    • PhoneGap (2009, devenu depuis Apache Cordova)
  • Côté serveur
    • Node.js (2009)
  • Publication de la spécification ECMAScript 5 (2009)

Presenter Notes

Les idiosyncrasies de JavaScript

Presenter Notes

Le nom

JavaScript n'a rien a voir avec Java.

Nom choisi pour des raisons marketing, pour conférer à JavaScript un peu de l'aura de Java.

Presenter Notes

La syntaxe

La syntaxe donne l'impression que JavaScript est similaire à Java ou C++.

for (i = 0; i < 10; i++) {
    myArray[i] = new Stuff();
}

Presenter Notes

Un langage souvent mal compris

  • impression : JavaScript ressemble à Java ou C++

  • réalité : JavaScript est très différent de ces langages

    • typage dynamique
    • des objets, mais pas de classes
    • sémantique différente du mot clé this
    • omniprésence de l'asynchrone
    • programmation fonctionnelle
    • portée des variables étendue aux fonctions et non aux blocs

Presenter Notes

Et aussi de vrais défauts

  • conversion de type bizarroïdes
  • variables globales par défaut
  • pas d'espaces de mommage

Presenter Notes

Typage dynamique

var myVar = 42;
myVar = "Bonjour !";
log(myVar);

Presenter Notes

Des objets mais pas de classes

  • objets littéraux
  • fonctions constructeurs
  • prototypes

Presenter Notes

Objets littéraux

var myObject = {
    name: "JavaScript",
    greet: function() {
        // définition de méthode
        log("Hello " + this.name);
    }
};
myObject.greet();

Presenter Notes

Fonctions constructeurs

Des fonctions ordinaires invoquée avec le mot clé new.

function MyConstructor() {
    this.name = "JavaScript";
    this.greet = function() {
        log("Hello " + this.name);
    };
}
myObject = new MyConstructor();
myObject.greet();

Presenter Notes

Prototypes

function ParentContructor() {
    this.name = "everyone";
    this.greet = function() {
        log("Hello " + this.name);
    };
}

function ChildContructor() {
    this.name = "JavaScript";
}
ChildContructor.prototype = new ParentContructor();

myObject = new ChildContructor();
myObject.greet();

Presenter Notes

Le mot clé this

var myObject = {
    firstName: "JavaScript",
    greet: function() {
        log("Hello " + this.firstName);
    }
};

function callingFunction(callback) {
    callback();
}

callingFunction(myObject.greet);

Presenter Notes

Code asynchrone

var myVar;

setTimeout(function() {
   myVar = 2;
}, 2000);

log(myVar);

Presenter Notes

Programmation fonctionnelle

function makeMultiplier(factor) {
     return function(number) {
         return number * factor;
     };
}

var doubler = makeMultiplier(2);

var doubles = [1, 2, 3].map(function(number) {
     return doubler(number);
});

log(doubles);

Presenter Notes

Portée des variables

var myVar = 2;
if (true) {
   var myVar = 3;
}
log(myVar);

var myVar = 2;

function assignMyVar() {
    var myVar = 3;
}

if (true) {
   assignMyVar();
}

log(myVar);

Presenter Notes

Conversion de types

log("0" == 0);

log("true" == true);

// http://www.wtfjs.com/2013/02/21/why-am-i-a-number
log("Why am I a " + typeof + "");

Presenter Notes

Variables globales par défaut

Ceci crée une variable globale :

function myFunc() {  
    myUglyGlobal = 42;
}
myFunc();

log(myUglyGlobal);

Presenter Notes

Pas d'espaces de nommage

<script src="http://example.com/some-other-script.js"></script>
<script src="my-own-script.js"></script>

Presenter Notes

Langages qui compilent en JavaScript

À causes des défauts, réels ou ressentis, de JavaScript, de nombreux langages qui compilent en JavaScript ont été créés:

  • CoffeeScript (ressemble à Python et Ruby)
  • ClojureScript (dialecte de Lisp)
  • Dart (Google)
  • TypeScript (Microsoft)

Problèmes : ajoute une couche de complexité, complique le déboguage (même si on a maintenant les source maps), besoin de traduire mentalement les docs de bibliothèques, etc.

Presenter Notes

Bonne pratiques

  • Utiliser les fonctions pour créer des espaces de nommage
  • Déclarer toutes ses variables avec var
  • Les opérateurs de comparaison triples
  • Connaître et utiliser les fonctionnalités de EcmaScript 5
  • Utiliser bind pour lier this à un objet
  • "use strict";

Presenter Notes

Module à base de fonction

// Revealing module pattern
var module = (function() {
    function myFunction() {
        log("éxécution de myFunction");
    }
    return {
        myFunction: myFunction
    }
}());

module.myFunction();

Presenter Notes

Utiliser var systématiquement

function f() {
    myGlobal = "Je suis globale.";
    var myLocal = "Je suis locale.";
    log(myGlobal + " " + myLocal);
}
f();

log(typeof myGlobal);

log(typeof myLocal);

Presenter Notes

Opérateurs de comparaison triples

log("0" == 0);

log("0" === 0);

Presenter Notes

Connaître et utiliser EcmaScript 5

var squares = [1, 2, 3].map(function(number) {
    return number * number;
});
log(squares);

var sum = [1, 2, 3].reduce(function(number, accumulator) {
    return accumulator + number;
}, 0);
log(sum);

Plus d'infos :

Presenter Notes

Utiliser bind pour fixer this

var myObject = {
    firstName: "JavaScript",
    greet: function() {
        log("Hello " + this.firstName);
    }
};

function callingFunction(callback) {
    callback();
}

callingFunction(myObject.greet.bind(myObject));

Presenter Notes

"use strict";

(function() {
    "use strict";
    myVar = 42;
    log(myVar);
}());
// Erreur dans la console :
// ReferenceError: assignment to undeclared variable myVar

(function() {
    "use strict";
    var myVar = 42;
    log(myVar);
}());

Presenter Notes

Évolutions à venir

ECMAScript 6 apporte des solutions à certains problèmes évoqués précédemment.

  • Fonctions flèches (arrow functions)
  • Modules
  • Classes

Presenter Notes

Les fonctions flèches (1/2)

Rappel du problème avec this et les fonctions normales :

function MyConstructor() {
    this.firstName = "JavaScript";
    this.greet = function() {
        log("Hello " + this.firstName);
    };
}

function functionCaller(callback) {
    callback();
}

var myObj = new MyConstructor();
functionCaller(myObj.greet);

Presenter Notes

Les fonctions flèches (2/2)

Solution avec une fonction flèche :

function MyConstructor() {
    this.firstName = "JavaScript";
    this.greet = () => {
        log("Hello " + this.firstName);
    };
}

function functionCaller(callback) {
    callback();
}

var myObj = new MyConstructor();
functionCaller(myObj.greet);

Presenter Notes

Modules

Définition d'un module :

// modules/helper.js
export function arrayToString(param) {  
    // some implementation
}

Et utilisation :

// application.js
import { arrayToString } from 'modules/helpers';

Tiré de Javascript ES6: Learn important features in a few minutes

Presenter Notes

Classes

class Project {  
  constructor(name) {
    this.name = name;
  }

  start() {
    return "Project " + this.name + " starting";
  }
}

var project = new Project("Journal");  
project.start(); // "Project Journal starting"

Presenter Notes

Et aussi

  • variables de niveau bloc avec le mot clé let
  • constantes avec le mot clé const
  • les generators avec le mot clé yield
  • et bien d'autres nouveautés

ES6 déjà en partie disponible dans les navigateurs et utilisable grâce à des transpilers comme Babel.

Presenter Notes

En conclusion

  • langage qui a végété à ses débuts
  • a pris son essor depuis 2005
  • des particularités et des défauts à connaître
  • de bonnes pratiques pour les dépasser
  • de nombreuses améliorations à venir

Presenter Notes