JavaScript, pour des applications Web
Depuis que Netscape a créé JavaScript pour programmer des pages HTML dynamiques, ses applications n'ont cessé de s'étendre.
Sa principale fonction et le scripting d'une page HTML ou d'une interface graphique (voir Qt, XAML, etc... Cela permet l'échange de données avec le serveur grâce à Ajax,
WebSocket, WebRTC.
Mais on l'utilise aussi pour permettre le scripting dans
des applications (Photoshop utilise
JavaScript) et même pour la programmation système!
JavaScript s'est appelé successivement Moka, puis LiveScript et finalement avec l'accord de Sun, JavaScript.
JScript est une version compatible implémentée par Microsoft en 2006, pour Windows uniquement.
Sa conception est un mélange de C et Self aus dires de l'auteur, Brendan Eich, qui était aussi amateur de Scheme. Le langage a de nombreux défauts, mais il est innovateur et flexible, et bien qu'il date de plus de 20 ans, il offre plus de possibilités que la plupart des langages plus récents, tel Dart. Et les implémenteurs oeuvrent à supprimer ces défauts.
Pour compléter ECMAScript 6 qui fait de JavaScript un langage d'application à part entière, Google a proposé en 2015 le mode SoundScript qui apporte en outre des variables typées et différentes accélérations à l'exécution. Mais ce projet a été abandonné en février 2016 et l'équipe a été réaffectée à Dart. Les variables typées sont cependant prévues dans une future version d'ECMAScript.
Court historique du langage
- 1995. Création par Brendan Eich (La même année que Java).
- 1996. Implémentation dans le navigateur Netscape 2.
- 1996. Microsoft implémente JScript, un langage compatible, dans Internet Explorer 3.
- 1997. Premier standard ECMAScript.
- 1999. ECMAScript 3.
- 2009. ECMAScript 5.
- 2011. Google veut remplacer JavaScript par Dart, mais se ravisera en 2015.
- 2012. Microsoft lance TypeScript, un sur-ensemble de JS avec classes qui est compilé en ECMAScript 5.
- 2013. Mozilla définit Asm.js, un sous-ensemble de JS utilisable comme bytecode.
- 2015. Google propose SoundScript, une version stricte qui facilite les optimisations pour les compilateurs.
- 2015. ECMAScript 6. Beaucoup d'éléments sont déjà implémentés dans les navigateurs.
Un langage ingénieux et innovant
Le format décrit ici est ECMAScript 1.5, défini par l'ECMA en 1999. Des versions plus récentes existent, mais ne sont pas supportées par tous les navigateurs.
Exemple de code: afficher les éléments d'une chaîne
- La syntaxe du langage est similaire à celle de Java ou C.
- Variables dynamiques. Déclarées comme "var", des données de types différents peuvent être assignées à une même variable. Firefox avec le version 9 introduit l'inférence de type qui fait que le compilateur peut traiter les variables comme typée et accélérer considérablement le traitement.
- Orienté objets, utilise les éléments de la page comme objets. Les objets sont dynamiques.
- Héritage par prototypes.
- Pas de gestion de fichier ni de fonctions d'entrées-sorties (sauf boites de dialogues).
La fonction d'écriture sur fichier local est inclus dans HTML 5 ou avec Node.js. - Contrôle du navigateur.
- Evènements.
- Tableaux dynamiques et associatifs.
- Les primitives (non déclarées) sont: boolean, string, number, date.
- Les objets Date, Math, RegExp sont prédéfinis.
- Un construct for .. in permet de scanner un tableau associatif.
- Les fonctions sont déclarées avec le mot-clé function, sans type de retour qui est optionel. Elles sont dite de première classe, autrement dit, on peut les utiliser comme des composants du langage, donc les assigner à des variable, les incorporer à des structures (comme des méthodes).
- Opérateurs d'ALGOL 68/C plus: === et !==, comparaisons sur valeur et sur type.
- Les éléments de la page sont réferencés comme une hiérarchie d'objets, incluant ceux du Document Object Model (DOM, un standard du W3C): document, window, form, table, etc...
- Le hoisting: ce qui est déclaré à l'intérieur d'un espace de visibilité, a sa déclaration déplacée au début. Par exemple, si on déclare une variable quelque part dans une fonction, elle sera en fait déclarée au début. De même les fonctions sont accessibles partout dans un script parce qu'elles sont déclarées au début du script.
Quelques défauts du langage...
- On ne peut pas remplacer un caractère dans une chaîne de caractères.
- L'addition d'une chaîne et d'un nombre n'est pas symétrique. Dans un cas cela retourne une chaîne, dans l'autre un nombre.
- Les comparaisons de booléens ne sont pas cohérentes.
- L'argument d'un constructeur de tableau peut être soit le nombre d'éléments, soit une liste d'éléments.
ECMAScript 7 pour des applications importantes et modulaires
Les nouvelles versions de JavaScript, tout en préservant la compatibilité, font de ce langage un outil plus sûr pour développer des applications d'envergure. On peut écrire du code ES6/ES7 et le faire traduire pour compatibilité avec tout navigateur par un outil comme TypeScript (Microsoft), Traceur (Google), ou Babel.
- let et const.
Ils servent à déclarer une variable ou une constante, soit globalement, soit localement. Let permet de déclarer une variable visible seulement dans un bloc d'instruction alors qu'avec var, même déclarée dans un bloc d'intruction elle est visible dans tout le corps de la fonction.
Let est similaire à with avec un gain en performance car il évite de créer un objet dynamique comme le fait with. - Map.
Tableau associatif ou les clés sont des objets, mais non pris en compte par le garbage collector. On peut retourner la liste des clés. Une valeur peut être retrouvée par get et une paire clé/valeur ajoutée par la méthode set. - WeakMap.
C'est un tableau associatif ou les clés ne peuvent être numériques, avec pour but d'associer des données à une liste d'objets.
Les clés sont des objets accessibles au garbage collector et il n'est pas possible d'obtenir une liste des clés sans la construire soi-même. - Set.
Contient une liste de valeurs, comme un tableau, mais ces valeurs doivent êtres uniques.
Map et WeakMap ont une méthode set, qui n'est pas capitalisée. La collection Set a les méthodes add et has mais pas de méthode pour obtenir directement un élément. - WeekSet
Tableau d'objets uniques. - Proxy.
Encore une source de confusion, il s'agit ici d'un meta-objet JavaScript, ou d'un objet virtualisé. Le comportement doit être entièrement défini par le programmeur. En créant un proxy d'un autre objet, on peut faire intercepter ses propriétés par le proxy, dans un but de supervision, déboguage ou autre. - Module.
En encapsulant le contenu d'un fichier dans module { } ou peut l'importer en entier ou en parties, pour les fonctions précédées du mot réservé export. Cela fonctionne comme dans Node.js. Cela s'accompagne de l'API Loader pour charger les modules. - Class .. extends
Des classes dotées d'héritage sont implémentées à coté des objets actuels. On peut seulement définir des attributs dans le constructeur. Section 14.5. - Array.from
Annule le défaut actuel du constructeur new Array(à. Avec from on assigne un argument qui est un tableau, et une propriété length donne la taille du tableau à créer. - For .. of
Enumère les valeurs des propriétés d'un tableau associatif. for(var v of x) remplace:
for(var k in x) { var v = x[k]; }
- Vous pouvez aussi obtenir les paires clé/valeurs avec: for(var [k,v] of x.
- Function * et yield
Ce type de fonction est une coroutine. Le mot-clé yield indique le but qui marque la fin de celle-ci. Cela remplace les callbacks de Node tout en conservant le mode asynchrone. (Chapitre 13.4 de la spécification). - Les fonctions auront aussi des valeurs par défaut pour les arguments omis.
- Promise. Objet devant contenir le résultat d'une opération délayée, ou asynchrone.
- Async/await. Rend synchrones les fonctions asynchrones.
- Template (Interpolation de chaîne)
Un nouveau type de chaîne litérale peut s'écrire sur plusieurs lignes et incorporer des variables. - Arrow. Nouvelle formulation pour une fonction lambda, qui peut s'écrire selon les deux formes ci-dessous.
function(a, b) { return a + b }
(a, b) => a + b - Les principales fonctionnalités de la version 2017 sont async/await et la mémoire partagée et les atomiques.
- Les Shared Array Buffer et Atomics sont des bases pour la programmation concurrente.
- Le langage devient un peut plus fonctionnel avec Object.value et Object.entries qui permettent d'énumérer les éléments d'un tableau ou les propriétés d'un objet.
Quelques nouvelles fonctionalités sont déjà implémentées dans un navigateur ou un autre. Pour savoir ce qui est implémenté dans un navigateur, utilisez le pour regarder les tests d'implémentation des nouvelles fonctionalités de JavaScript.
Pour activer certaines de ces fonctions sous Chrome, il faut entrer chrome:flags et Enable Experimental JavaScript.
Référence: ECMA Standard Specification for 7th Edition. 2016.
Quel interpréteur JavaScript pour quel navigateur?
Les navigateurs se font concurrence sur les moteurs JavaScript comme sur les moteurs de rendu... Mais ce sont maintenant plutôt des compilateurs JIT que des interpréteurs...
- V8. Le compilateur de Chrome et de Node.js.
- JavaScriptCore. Celui de WebKit et Safari. On lui donne aussi d'autres noms commerciaux: Nitro, SquirrelFish. Mais c'est le même engin.
- SpiderMonkey. Celui de Firefox.
- IonMonkey. Un JIT spécifique pour Firefox (depuis 18) qui s'exécute seulement sur le code Asm.js. Le plus rapide en mai 2014.
Hashorn produit du bytecode pour la JVM. Intégré à aucun navigateur majeur.
Un langage système?
Avec l'apparition des compilateurs JavaScript, fonctionnant aussi bien dans le navigateur que comme outil indépendant, de nouvelles utilisations voient le jour pour ce langage proche de C mais plus libre encore et disposant d'une gestion automatique de mémoire, de sandbox.
- JSLinux.
Ce projet permet de faire tourner Linux dans le navigateur. On peut éditer des programmes, les compiler et les exécuter en ligne de commande. - LLVM.js.
Il est possible de compiler tout langage LLVM (C++, Julia) en JavaScript: le bitcode LLVM est traduit en JavaScript par LLVM.js.
JavaScript est-il lent sur les mobiles?
La polémique a été lancée par un article de Drew Crowford selon lequel JavaScript est trop lent parce que les mobiles ont peu de mémoire comparativement aux ordinateurs de bureau.
Mais d'autres spécialistes du langage ne sont pas d'accord et pensent que le coupable n'est pas le langage, c'est le DOM. On sait que DOM est lent, c'est pourquoi certains frameworks comme Angular ont implémenté le data-binding qui permet de mettre à jour le contenu sans passer par lui.
L'auteur précise qu'en fait, JavaScript peut être plus rapide que d'autres langages comme Objective-C (utilisé sur iOS) dans l'échange de messages car c'est quelque chose qui fonctionne mieux avec un JIT qu'avec une compilation statique.
Finalement l'auteur attribue la rapidité des applications natives iOS au fait que l'écran ait une taille unique, contrairement à Android ou autres systèmes.
Même si le langage est relativement facile à apprendre, il a des points obscurs, au point qu'on a des livres spécialisés dans les bonnes parties du langage, d'autres sur les aspects complexes.
- Tutoriel JavaScript en français
Avec description de la syntaxe, exemples et démonstrations. Essentiellement les bonnes parties... - JSON.
Un format de données à syntaxe JavaScript. - ECMAScript.
La spécification de 1999 langage JavaScript. - Le futur de JavaScript
Par Brendan Eich, un diaporama décrit le développement du langage. Le but est que JS convienne pour les applications, les bibliothèques et qu'il remplace une machine virtuelle. - Liste des langages qui ont un compilateur vers JavaScript
La liste est impressionante et inclut Go, Dart, Python, Ruby, Java, Scala, Basic, Pascal, C and C++ par l'intermédiaire de Emscriptem.
- TypeScript. (Microsoft) Conçu pour étendre JavaScript, à la même syntaxe.
- Traceur. Compilateur de ECMAScript 6 en 5 par Google.
- Scriptol. Support complet du language Scriptol avec programmation réactive.
- Emscriptem compile du bytecode LLVM en JavaScript. Donc tout langage compilé par LLVM tel que C++ peut être converti en JavaScript et fonctionner dans le navigateur. Go peut être converti avec Gopherjs.
- Babel.(Ex 6to5) Permet d'écrire du code en ES6 ou ES7, avec classes, getters, valeurs d'arguments par défaut, il sera compilé en JS classique.
Vous pouvez développer une application en JavaScript sous LightTable (voir image plus haut), Eclipse, NetBeans ou Aptana, ou un éditeur de texte pour un simple script.
- Karma.
Par Google, teste le code pour tous les navigateurs, à partir de l'éditeur. - JSLint est un outil en ligne pour tester votre code JavaScript et détecter les erreurs (par le créateur de JSON).
- Duktape
Un moteur JavaScript à embarquer dans une application en C ou C++, pour ajouter une possiblité de scripting ou du code dynamique. Il suffit d'ajouter duktape.c et duktape.h à la liste des sources du projet. On peut alors appeler les fonctions JS 5 à partir de C et inversement.
- Node.js.
Le compilateur V8, s'utilise en ligne de commande avec Node (voir la section JavaScript sur ce site), et utiliser les bibliothèques NPM.
Electron combine Node et le navigateur Chrome pour des applications locales.
Il est recommandé d'utiliser un framework Ajax ou HTML 5 pour développer une application sérieuse. Il existe aussi des frameworks pour mobiles.
- River Trail.
Extension à JavaScript sous la forme d'un plugin qui permet la programmation parallèle. Utilisé dans WebGL par exemple, il permet de gérer des milliers d'objets simultanément. - Frameworks HTML 5
Librairies JavaScript utilisant Canvas. - Moteurs de jeux
Ils font la moitié du développement. - Algorithms and data structures.
Compilation sur GitHub.
JavaScript devient le langage des applications Linux
Linux
Evidemment cela provoque des protestations car chaque développeur a son langage favori (C, Python, Ruby, etc.) qu'il aurait voulu voir choisi pour ce rôle.
L'autre environnement de référence, KDE, étant basé sur Qt, utilise aussi JavaScript pour l'interface et C++ pour les applications. Toutefois l'interface Plasma, qui est l'équivalent de Metro pour Linux, permet la création rapide d'applications en JavaScript avec l'IDE Plasmate.