Les fonctions et paramètres
Les fonctions nommées

Tout à fait Arthur, c'est un concept de développement très courant, qui permet de réutiliser autant qu'on le souhaite une suite d'instructions.

Et bien si on imagine un programme qui dit affiche l'heure, on pourrais faire ça :
{"language":"application/json","content":"var date = new Date();\nconsole.log(date);","filename":""}

Mais si on doit afficher l'heure de nombreuses fois, il faudrait répéter ces deux lignes de code systématiquement. A la place on peut créer une fonction afficherHeure qui s'en occupera à notre place :
{"language":"application/json","content":"function afficherHeure(){\n\tvar date = new Date();\n\tconsole.log(date);\n}","filename":""}
Et il nous suffit ensuite d'appeler cette fonction autant de fois que nécessaire pour afficher l'heure :
{"language":"application/json","content":"function afficherHeure(){\n\tvar date = new Date();\n\tconsole.log(date);\n}\n\nafficherHeure();\nafficherHeure();\nafficherHeure();","filename":""}

Exactement, l'exemple que je viens de faire s'appelle une fonction nommée en js, car on lui a donné un nom.

Les paramètres
Tout à fait, mais on y reviendra plus tard, avant ça je vais te parler de paramètres. Les fonctions sont pratiques, mais il faut aussi pouvoir les adapter. imaginons une fonction qui dit bonjour à quelqu'un, l'idéal serait qu'elle s'adapte au nom de la personne. Mais la fonction en elle même ne connais pas le nom de cette personne d'avance, on va donc lui passer ce nom en paramètres pour qu'elle puisse l'utiliser :
{"language":"application/json","content":"function direBonjour(prenom){\n\tconsole.log(\"Bonjour \" + prenom);\t\n}\n\ndireBonjour(\"Aurélien\"); // Affiche \"Bonjour Aurélien\"\ndireBonjour(\"Julien\"); // Affiche \"Bonjour Julien\"\ndireBonjour(\"Clémence\"); // Affiche \"Bonjour Clémence\"\ndireBonjour(\"Marie\"); // Affiche \"Bonjour Marie\"","filename":""}
Tu vois ici j'ai définit un paramètre prénom à ma fonction, c'est un peu comme une variable, mais qui n'existera que dans le contexte de cette fonction, on pourra ainsi lui passer une valeur différente à chaque fois.

Non, je l'ai fait pour l'exemple, mais en général on va plutôt utiliser des variables pour rendre notre code plus générique. Par exemple on pourrait récupérer la liste des employés à partir d'une base de données, et les afficher grace à une fonction, pour l'exemple je définit ça dans un tableau, mais imagine que ce tableau soit récupéré d'ailleurs :
{"language":"application/json","content":"var listEmploye = [{\n\t\"nom\": \"Dupond\",\n\t\"prenom\": \"Jean\",\n\t\"age\": 31,\n\t\"poste\": {\n\t\t\"titre\": \"Ingénieur étude et développement\",\n\t\t\"dateEntree\" : \"17/10/2017\"\n\t}\n},{\n\t\"nom\": \"Dufresne\",\n\t\"prenom\": \"Marina\",\n\t\"age\": 24,\n\t\"poste\": {\n\t\t\"titre\": \"Chef de projet\",\n\t\t\"dateEntree\" : \"02/01/2019\"\n\t}\n}];\n\n\n\nfunction afficherEmploye(employe){\n\tconsole.log(\"Nom : \" + employe.nom);\n\tconsole.log(\"Prenom : \" + employe.prenom);\n\tconsole.log(\"Age : \" + employe.age);\n}\n\nfor(let employe of listEmploye){\n\tafficherEmploye(employe);\t\n}","filename":""}
Résultat :


Et bien non, c'est le gros avantage de la portée dont on a déjà parlé, le employe dans la boucle n'existe que dans la boucle, et celui dans la fonction n'existe que dans la fonction, donc ce sont bien deux variables différentes.

Passage par valeur et par référence
Par contre il faut faire attention au passage par valeur et par référence.

Quand on passe un paramètre à une fonction, de manière générale en informatique, on peut le faire par valeur et par référence. C'est une différence fondamentale.
Le passage par valeur va créer une copie de la variable pour qu'elle soit utilisée dans la fonction, alors que le passage par référence va passer un "lien" vers la variables pour qu'elle soit utilisée par la fonction. En javascript par défaut les variables sont passée par valeur, sauf si ce sont des objets et dans ce cas elles sont passées par référence.

Et bien un passage par valeur est une copie, donc si on modifie la valeur du paramètre dans la fonction, ça ne changera que le paramètre et pas la variable qui a été passée. Par contre un passage par référence étant lié, si on modifie le paramètre dans la fonction, ça va aussi modifier la variable qui a été passée. Pour te montrer la différence voici un passage par valeur :
{"language":"application/json","content":"var x = 5;\n\nfunction double(x){\n x *= 2;\n\tconsole.log(x);// affiche 10\n}\n\ndouble(x);\nconsole.log(x);// affiche 5","filename":""}
Ici on voit bien que le paramètre x a été doublé avant d'être affiché, mais la variable x n'as pas été modifiée par la fonction. Par contre si on utilise un objet :
{"language":"application/json","content":"var x = {value : 5};\n\nfunction double(value){\n\tx.value *= 2;\n\tconsole.log(x);// affiche {value: 10}\n}\n\ndouble(x);\nconsole.log(x);// affiche {value: 10}","filename":""}
Cette fois ci notre variable a été modifiée par la fonction ! C'est un passage par référence.

Parce qu'il est indispensable de le savoir, sinon à ton premier passage par référence, tu ne va pas comprendre pourquoi ton code modifie ton objet.
Il faut aussi savoir que l'on peut passer plusieurs paramètres à une fonction, il suffit de les séparer par une virgule :
{"language":"application/json","content":"function addition(a, b){\n\tconsole.log(a + b);\n}\n\naddition(5,3);// affiche 8","filename":""}

Retour de fonction
Et depuis tout à l'heure je ne fait que des console.log dans mes fonctions, mais il faut aussi savoir qu'une fonction peut retourner quelque chose, il suffit d'utiliser le mot clé return :
{"language":"application/json","content":"function addition(a, b){\n\treturn a + b;\t\n}\n\nvar total = addition(5,3);\nconsole.log(total);","filename":""}

Et on peut aussi passer autre chose que des variables ou des valeur à une fonction.

Passage de fonction en paramètre
Et bien une fonction peut être passée comme paramètre à une autre fonction.

Oui, et il faut bien faire attention aussi, comme je t'ai parlé tout à l'heure du passage par valeur et par référence, on a un concept similaire pour les fonctions, on peut passer le résultat d'une fonction, ou la référence de la fonction.

Pour le passage de valeur c'est assez simple, on va appeler une fonction qui retourne une valeur, et utiliser cette valeur pour la passer à une autre fonction. Par exemple, si on a deux fonctions, une qui récupère la date et la formate, et une autre qui affiche un message "Nous sommes le {j/m/a}", on peut utiliser la première pour la passer à la deuxième en plusieurs lignes ça donnerais :
{"language":"application/json","content":"function dateFormatee(){\n\tvar date = new Date();\n\treturn date.toLocaleDateString();\n}\n\nfunction afficherDate(date){\n\tconsole.log(\"Nous somme le \" + date);\t\n}\n\nvar dateFormate = dateFormatee();\nafficherDate(dateFormate);","filename":""}
Mais passer par une variable est une ligne un peu inutile, on pourrais directement faire :
{"language":"application/json","content":"function dateFormatee(){\n\tvar date = new Date();\n\treturn date.toLocaleDateString();\n}\n\nfunction afficherDate(date){\n\tconsole.log(\"Nous somme le \" + date);\t\n}\n\nafficherDate(dateFormatee());","filename":""}
Et ça fonctionne tout aussi bien !

Je t'ai parlé de passage par référence pour comparer, mais quand on passe une fonction à une autre fonction, on appelle cela un callback. En fait la fonction appelée pourra elle même appeler le callback dans son exécution.
{"language":"application/json","content":"function faireUnTruc(callback){\n\tcallback();\t\n}\n\nfunction afficherDate(){\n\tvar date = new Date();\n\tconsole.log(date.toLocaleDateString());\n}\n\nfunction afficherHello(){\n\tconsole.log(\"Hello\");\n}\n\nfaireUnTruc(afficherDate);// affiche la date\nfaireUnTruc(afficherHello);// affiche \"Hello\"","filename":""}
Tu remarquera, à la différence de précédemment j'ai passer le nom de la fonction mais sans mettre les parenthèses après. C'est là qu'est la nuance, quand on met des parenthèse après un nom de fonction, c'est pour lui dire d'exécuter cette fonction, quand on ne les met pas, c'est pour faire référence à la fonction, mais sans l'éxecuter.

Les fonctions anonymes
Et bien, pour répondre à ta question de tout à l'heure, il existe des fonctions qui ne sont pas nommées, ce sont les fonctions anonymes. Et on va s'en servir très souvent pour créer un callback dans une fonction. Pour t'expliquer plus en détail pourquoi, il faut d'abord comprendre que le javascript est asynchrone, c'est à dire que lorsqu'une instruction est lancée, on ne va pas nécessairement attendre qu'elle soit terminée pour lancer l'instruction suivante. Bien entendu ce que l'on a fait jusque maintenant, l'affectation de variables, l'utilisation de structures conditionnelles et itératives est totalement synchrone, mais beaucoup d'autres instructions ne le sont pas.
Dans ces cas là, si l'on souhaite faire quelque chose en particulier lorsque cette instruction asynchrone est terminée, on ne peut pas le mettre juste après, sinon elle pourrait être exécutée avant la fin. Par exemple la fonction setTimeout va attendre un temps prédéfinit puis exécuter un code.
{"language":"application/json","content":"setTimeout(function(){\n\tconsole.log(\"Hello\");\n},1000) // attend 1000 millisecondes => 1 seconde\nconsole.log(\"World\");","filename":""}
Cet exemple va afficher "World" et seulement ensuite "Hello".

Et oui, en appelant le setTimeout on lui dit d'attendre 1 seconde avant d'afficher "Hello", puis on lui demande d'afficher "World", qu'il fait immédiatement, puis une seconde plus tard, il va afficher "Hello".
Et si tu regarde bien le code, setTimeout est une fonction à laquelle on a envoyé deux paramètres, le deuxième et le temps à attendre, et le premièr c'est une fonction anonyme, utilisé comme callback.

On aura l'occasion d'en voir plusieurs les prochains jours, entre autre avec la gestion des événements qui est totalement asynchrone ! Pour aujourd'hui c'est terminé.

Une chose à la fois, demain on verra le DOM déjà, on va arrêter les consoles.log et commencer à faire un vrai site en javascript !
