title: JavaScript de zéro
slug: javascript-zero
date: 2016-01-18
chapo: Enseigner JavaScript ET la programmation à partir de zéro est un moyen d’identifier les forces et faiblesses du langage.
> When it comes to problem-solving in general (and JavaScript in particular), I have a similar bias towards single-purpose solutions. Rather than creating a monolithic framework that attempts to solve all possible problems, I prefer a collection of smaller scripts that only do one thing, but do it really well; [the UNIX philosophy](https://en.wikipedia.org/wiki/Unix_philosophy).
>
> *[Small lessons, loosely learned](https://adactio.com/journal/10078)* ([cache](/david/cache/5ca3d2195e5b23f6dca45fcab9327040/))
En un temps relativement restreint (8 heures [de cours](/david/pro/enseignement/)), j’ai essayé d’enseigner JavaScript à des étudiants n’ayant aucune notion de programmation en ne partant finalement [d’aucun niveau d’abstraction](/david/blog/2015/javascript-abstraction/). Pour seuls outils : le navigateur et son inspecteur/console et un fichier `HTML` de test, l’objectif étant d’alterner entre du théorique avec ce fichier et du pratique en manipulant des pages existantes. J’appréhendais un peu suite [aux désillusions de l’année dernière](/david/blog/2015/cours-iut-comprendre-javascript/) mais j’avais gagné en expérience à la fois en JS et en réduisant mes prétentions sur ce que je voulais leur transmettre.
La première heure, compréhension des notions de variable et d’opérateur puis introduction de `console.log` pour faire la différence entre un script et son exécution dans la console. La deuxième heure a été consacrée à `document.querySelector` et `document.querySelectorAll` où l’on parle forcément de tableaux/listes et c’est peut-être à ce moment là que j’aurais dû introduire la conversion d’un `NodeList` en `Array` mais on n’en avait pas encore le besoin… En troisième heure, on commence à jouer avec les styles avec `Element.style` et surtout `Element.classList` et ça commence à être ludique d’aller modifier des pages existantes. Enfin pour clôturer la session, on expérimente avec `innerHTML` et `outerHTML` pour introduire du dynamisme. Et de manière transverse on parle de `NaN`, d’`undefined` et des commentaires.
À la fin de cette première demi-journée j’étais très optimiste car tous les étudiants avaient compris et savaient appliquer ce genre de code (valide) :
:::html
Test JavaScript
red
green
blue
Mine de rien ça fait énormément de concepts à assimiler pour les 24 personnes n’ayant jamais fait de programmation ! Et la transition est toute trouvée pour parler de la répétition avec les boucles et les fonctions. Hop, une semaine de repos pendant laquelle ils n’ont… rien fait :’(.
Voir ces 3 lignes répétées doit faire bondir un développeur, j’ai commencé par introduire la notion de fonction avec un nom suffisamment explicite pour limiter les commentaires puis l’usage d’une boucle `for` pour itérer sur les éléments. Au passage on a besoin d’`Array.length` et de comprendre les conditions. Jusque là tout allait bien, j’en profite pour montrer qu’il est possible de le faire avec un `while` et déjà ça amène de la confusion mais alors là où ça a vraiment bloqué c’est au passage à `forEach`. Je ne sais pas si c’est la syntaxe ou la conversion en `Array` ou le fait d’avoir des fonctions anonymes ou la fatigue cognitive mais toujours est-il que ça a commencé à décrocher à ce moment là. Il faut dire qu’un `Array.prototype.slice.call` en plein milieu n’arrange pas les choses. Peut-être qu’un `Array.from` ou un `for(… of …)` eut été plus explicite mais limité en terme de support. Dur.
Pour finir, j’ai montré qu’une fonction pouvait retourner une valeur avant d’enchaîner sur les évènements à base d’`addEventListener` ce qui ouvre la porte des interactions avec l’utilisateur. On arrive à cet enchaînement :
:::javascript
function addClassFromHTML(element) {
element.classList.add('turn-' + element.innerHTML)
}
function dealWithTitleOnClick(title) {
title.addEventListener('click', function() {
addClassFromHTML(title)
})
}
var titles = document.querySelectorAll('h1')
titles = Array.prototype.slice.call(titles)
titles.forEach(dealWithTitleOnClick)
Je retiendrai qu’il faut un peu plus de temps pour découvrir certains concepts. Travail demandé pour la semaine suivante : faire une fonction qui permette à partir d’un article de presse d’avoir une version lisible avec uniquement le titre et le contenu sans images. Une sorte de *bookmarklet* à la [readability](https://github.com/mozilla/readability). Et [jouer](http://codecombat.com/) aussi.
**Enseigner JavaScript ET la programmation à partir de zéro est un moyen d’identifier les forces et faiblesses du langage.** D’un côté on a le [TDD du pauvre](/david/blog/2013/tdd-conception-emergente/) avec un feedback visuel immédiat et la possibilité d’utiliser la console du navigateur. De l’autre les plusieurs façons de faire la même chose et les restrictions liées au non-support d’ES6 par les navigateurs. J’ai presque envie de troller sur la programmation fonctionnelle mais je vais plutôt ajouter [une couche d’abstraction](/david/blog/2015/javascript-abstraction/) pour la prochaine fois, ce sera plus simple en demi-groupes. En espérant que ça devienne davantage compréhensible et utilisable par des néophytes, le code précédent devenant :
:::javascript
$('h1').on('click', function(event) {
addClassFromHTML(event.target)
})