Ces articles sont faits pour vous aider à apprendre comment utiliser three.js. Ils supposent que :
<script type="module">
;Voici ci-dessous quelques rappels et notes.
Les modules es6 peuvent être chargé via le mot-clé import
dans un script
ou en ligne via une balise <script type="module">
. Voici un exemple des deux
<script type="module"> import * as THREE from '../../build/three.module.js'; ... </script>
Les chemins doivent être absolus ou relatifs. Ces derniers débutent toujours par ./
ou ../
,
ce qui est différent des autres balises telles que <img>
, <a>
et les références css.
Davantage de détails se trouvent à la fin de cet article.
document.querySelector
et document.querySelectorAll
Vous pouvez utiliser document.querySelector
pour sélectionner le
premier élément qui correspond à un sélecteur CSS.
document.querySelectorAll
retourne tous les éléments qui correspondent
à un sélecteur CSS.
onbody
n'est pas nécessaireBeaucoup de pages vielles d'il y a 20 ans utilisent
<body onload="somefunction()">
Ce style est déprécié. Mettez vos scripts à la fin de la page.
<html> <head> ... </head> <body> ... </body> <script> // inline javascript </script> </html>
ou utilisez la propriété defer
.
function a(v) { const foo = v; return function() { return foo; }; } const f = a(123); const g = a(456); console.log(f()); // affiche 123 console.log(g()); // affiche 456
Dans le code ci-dessus, la fonction a
créé une nouvelle fonction chaque fois qu'elle est appelée.
Cette fonction se clôt sur la variable foo
. Voici davantage d'information.
this
this
est une variable passée automatiquement aux fonctions tout comme les arguments y sont passés.
Une explication simple est que quand vous appelez une fonction directement comme ceci :
somefunction(a, b, c);
this
prendra la valeur null
(dans le cas du mode strict ou d'un module) tandis que lorsque vous
appelez une fonction via l'opérateur .
comme ceci :
someobject.somefunction(a, b, c);
this
sera une référence vers someobject
.
Ce fonctionnement peut dérouter lorsqu'il est combiné avec les fonctions de rappel (callbacks).
const callback = someobject.somefunction; loader.load(callback);
Ceci ne fonctionne pas comme s'y attendrait une personne inexpérimentée parce que, quand
loader.load
appelle la fonction de rappel, il n'utilise pas l'opérateur .
et donc
par défaut this
est null (à moins que loader le fixe arbitrairement à une valeur).
Si vous souhaitez que this
se rapporte à someobject
quand la fonction de rappelle
est activée, vous devez dire à Javascript de le lier à la fonction.
const callback = someobject.somefunction.bind(someobject); loader.load(callback);
Cet article peut aider à expliquer this
.
var
est déprécié. Privilégiez l'usage de const
et/ou let
Il n'y a PLUS AUCUNE raison d'utiliser var
. L'utiliser est dorénavant considéré
comme une mauvaise pratique. Utilisez const
si la variable n'est jamais réaffectée,
ce qui se passe dans la majorité des cas. Utilisez let
dans le cas où la valeur change.
Cela aidera à éviter beaucoup de bogues.
for(elem of collection)
jamais for(elem in collection)
for of
est récent, for in
est ancien. for in
avait des problèmes résolus par for of
Voici un exemple où vous pouvez itérer au travers de toutes les paires clef/valeur d'un objet :
for (const [key, value] of Object.entries(someObject)) { console.log(key, value); }
forEach
, map
, et filter
quand c'est utileLes fonctions forEach
,
map
, et
filter
ont
été ajoutées aux tableaux (arrays) et sont utilisés de manière assez intensives en JavaScript moderne.
Soit l'objet const dims = {width: 300, height: 150}
ancien code
const width = dims.width; const height = dims.height;
nouveau code
const {width, height} = dims;
ancien code :
const width = 300; const height = 150; const obj = { width: width, height: height, area: function() { return this.width * this.height }, };
nouveau code :
const width = 300; const height = 150; const obj = { width, height, area() { return this.width * this.height; }, };
...
L'opérateur d'expansion a de multiples usages. Voici un exemple :
function log(className, ...args) { const elem = document.createElement('div'); elem.className = className; elem.textContent = [...args].join(' '); document.body.appendChild(elem); }
et un autre exemple :
const position = [1, 2, 3]; somemesh.position.set(...position);
class
La syntaxe pour créer des objets au comportement de classe avant ES5
n'était connue que des programmeurs chevronnés. Depuis ES5, vous pouvez
à présent utiliser le mot-clef class
qui est plus proche du style C++/C#/Java.
Getters et
setters sont
communs dans la plupart des langages modernes. La syntaxe de type class
de ES5 les rend plus faciles à employer qu'avant.
Cela est particulièrement utile avec les fonctions de rappel (callbacks) et les promesses (promises).
loader.load((texture) => { // utiliser la texture });
Les fonctions fléchées se lient avec this
. Ainsi
const foo = (args) => {/* code */};
est un raccourci pour
const foo = (function(args) {/* code */}).bind(this));
Les promesses (promises) aident à l'utilisation de code asynchrone. Async/await aident à l'utilisation des promesses.
Cela nécessiterait des développements trop long à détailler ici. Toutefois, vous pouvez en lire davantage sur les promesses ici et sur async/await ici.
Les gabarits de libellés sont des chaînes de caractères délimitées par des accents graves au lieu d'apostrophes doubles (quotes).
const foo = `this is a template literal`;
Les gabarits de libellés ont deux particularités. La première est d'être multi-ligne
const foo = `this is a template literal`; const bar = "this\nis\na\ntemplate\nliteral";
ainsi foo
et bar
ci-dessus sont similaires.
L'autre particularité est que vous pouvez sortir du mode chaîne et insérer des fragments
de code Javascript en utilisant ${javascript-expression}
.
C'est l'objet des gabarits. Par exemple :
const r = 192; const g = 255; const b = 64; const rgbCSSColor = `rgb(${r},${g},${b})`;
ou
const color = [192, 255, 64]; const rgbCSSColor = `rgb(${color.join(',')})`;
ou
const aWidth = 10; const bWidth = 20; someElement.style.width = `${aWidth + bWidth}px`;
Alors que vous êtes libre de formater votre code comme vous le souhaitez, il y a au moins une convention dont vous devez avoir connaissance. Les variables, les noms de fonctions et de méthodes sont toutes en lowerCasedCamelCase (c'est à dire que les mots formant les noms des entités sont collés les uns aux autres et leur première lettre est en majuscule, les autres en minuscules à l'exception de la toute première lettre du nom qui est également en minuscule -- NDT). Les constructeurs, les noms des classes sont en CapitalizedCamelCase ( les mots formant les noms des entités sont collés les uns aux autres et leur première lettre est en majuscule, les autres en minuscules -- NDT). Si vous suivez cette règle, votre code ressemblera à la plupart des autres écrits en JavaScript. Beaucoup de linters, qui sont des programmes vérifiant les erreurs dans votre code, mettrons en évidence des erreurs si vous utiliser la mauvaise casse puisqu'en suivant la convention ci-dessus ils sauront que ces lignes ci-dessous sont mauvaises :
const v = new vector(); // évidemment une erreur si toutes les classes commencent par une majuscule. const v = Vector(); // évidemment une erreur si toutes les fonctions commencent par une minuscule.
Bien sûr, vous pouvez utiliser l'éditeur de votre choix mais, si vous ne l'avez pas encore essayé, envisagez d'utiliser Visual Studio Code pour JavaScript et après l'avoir installé, intégrez-y eslint. Cela vous prendra quelques minutes à installer mais vous aidera grandement pour trouver les bogues de votre JavaScript.
Quelques exemples
Si vous activez la règle no-undef
alors VSCode via ESLint vous avertira de l'utilisation de nombreuses variables non définies.
Ci-dessous vous pouvez voir que nous avons écrit doTheThing
à la place doThing
.
doThing
se retrouve souligné en rouge et un passage au dessus me dira que
c'est non défini. Une erreur est donc évitée.
Vous aurez des avertissements (warnings) en utilisant THREE
donc ajoutez /* global THREE */
en haut de vos fichiers JavaScript pour notifier à eslint que THREE
existe.
Ci-dessus, vous pouvez voir que eslint connaît la règle que les noms commençant par
une majuscule UpperCaseNames
sont des constructeurs et vous devez donc utiliser new
.
Une autre erreur évitée. C'est la règle new-cap
rule.
Il y a des centaines de règles que vous pouvez activer, désactiver ou personnaliser.
Par exemple, précédemment nous avons indiquer que nous devions utiliser const
et let
à la place de var
.
Ici nous avons utilisé var
et nous avons été avertis que nous devions utiliser let
ou const
Ici nous avons utilisé let
mais comme la valeur de la variable ne change jamais, nous
nous voyons suggérer l'utilisation de const
.
Bien sûr, si vous préférez conserver var
, vous pouvez désactiver cette règle.
Comme écrit plus haut, nous préférons privilégier const
et let
à la place de var
puisqu'ils sont plus efficaces et évitent les bogues.
Pour les cas où vous avez vraiment besoin d'outrepasser une règle, vous pouvez ajouter un commentaire pour les désactiver pour une seule ligne ou une section de code.
La plupart des navigateurs se mettent à jour automatiquement donc utiliser les subtilités vues plus haut vous aiderons à être productif et éviter les bogues. Ceci étant dit, si vous êtes dans un projet qui doit absolument supporter des vieux navigateurs, il y a des outils qui interpréterons votre code ES5/ES6/ES7 et le transpilent en code JavaScript pre-ES5.