11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour. Dans ma course de fond pour remplacer mes anciens scripts jQuery je me penche aujourd'hui sur la fonction .siblings().

Donc voilà ce que j'ai fais (et ici un CodePen) :
const siblings = el => {
  for (let sibling of el.parentNode.children) if (sibling !== el) sibling.classList.add('color')
}
// et l'appel :
const el = document.querySelector('.test > :nth-child(4)')
siblings(el)

Mais j'ai un problème de compréhension par rapport aux arguments de ma fonction. Je pensais qu'il était obligatoire de les déclarer dans la fonction, mais quoi que je fasse j'ai le même résultat, ça marche dans tous les cas :
const siblings = el => {}

const siblings = () => {}

Je ne comprends pas comment c'est possible, quelque chose m'échappe dans la compréhension des fonctions fléchées (ou même des fonctions tout court). Pourriez-vous m'expliquer cela ?
Modifié par Olivier C (19 Jun 2020 - 15:13)
Serait-ce par exemple que le passage d'une variable en argument dans la fonction est implicite et qu'il faudrait la déclarer que si l'on voulait changer son nom pour la fonction ?
const siblings = n => {/* 'el' est renomée ici en 'n' */}
siblings(el)

Modifié par Olivier C (19 Jun 2020 - 15:25)
Modérateur
Et l'eau Olivier Smiley smile

La règle est simple :
Si tu as seulement un argument dans la signature de ta fonction, tu peux omettre les parenthèses. En revanche, s'il n'y a pas d'argument ou qu'il y a plusieurs arguments, on ajoute les parenthèses.

Olivier C a écrit :
Serait-ce par exemple que le passage d'une variable en argument dans la fonction est implicite et qu'il faudrait la déclarer que si l'on voulait changer son nom pour la fonction ?
const siblings = n => {/* 'el' est renomée ici en 'n' */}
siblings(el)


Je comprends pas bien ce que tu dis. Une arrow function c'est une function classique. À la différence, tu peux lui passer le contexte.


var carre = function(a){
    return a*a;
};

var trois = 3;
console.log(carre(trois));

Modifié par niuxe (19 Jun 2020 - 18:28)
Merci pour ton intervention Niuxe.
J'avais vu sur la spec pour l'omission des parenthèses si argument unique. Ce qui me perturbe ici c'est que la fonction tourne même sans passer AUCUN argument, alors que dans les fait la fonction en a besoin d'un.
Voili voilou...
Bonjour,


Const el est déclarée en global donc que tu le passes en argument de la fonction ou pas de toutes façons il est vu dans la fonction.
Meilleure solution
Modérateur
Dev-Web-06 a écrit :
Bonjour,


Const el est déclarée en global donc que tu le passes en argument de la fonction ou pas de toutes façons il est vu dans la fonction.


oui mais c'est pas tout à fait ça. C'est le scope parent.

Pour comprendre mon exemple, voici 2 scripts :

var quelqueschose = function(){
    return trois;
};

const trois = 3;
console.log(quelqueschose()); // 3



var quelqueschose = function(){
    return trois;
};

console.log(quelqueschose()); // undefined
const trois = 3;


Ce n'est pas du tout le même mécanisme que php. Une const n'est accessible que par son scope. Or en php, une constante est globale. En Python, les constantes n'existent pas vraiment. Il y a les tuples. Les tuples, c'est un peu comme un array. Mais les valeurs à l'intérieur ne peuvent être modifiées. La portée des variables dans Python, c'est la même que le JS.

Petite anecdote qui va vous éviter bien des déboires ! L'année dernière, j'ai récupéré des fichiers js où je devais ajouter 3 features. Le script principale faisait plus de 800 lignes. La personne qui avait codé ça avait fait du pseudo objet et il jouait sur la portée des variables ! Au lieu de livrer le projet en 3 jours, j'ai mis le double (avec charette) ! Smiley fache
Modifié par niuxe (19 Jun 2020 - 19:54)
Dev-Web-06 a écrit :
Const el est déclarée en global donc que tu le passes en argument de la fonction ou pas de toutes façons il est vu dans la fonction.

@Dev-Web-06 : C'était effectivement cela apparemment car si je fais :
siblings(document.querySelector('.test > :nth-child(4)'))

... je n'ai plus d'effet de bord.

Maintenant @Niuxe ta remarque reste tout à fait pertinente : si la variable globale est appliqué après un appel à la fonction - comme dans ton exemple - aucune chance que ça marche, effectivement...

niuxe a écrit :
Petite anecdote qui va vous éviter bien des déboires ! L'année dernière, j'ai récupéré des fichiers js où je devais ajouter 3 features. Le script principale faisait plus de 800 lignes. La personne qui avait codé ça avait fait du pseudo objet et il jouait sur la portée des variables ! Au lieu de livrer le projet en 3 jours, j'ai mis le double (avec charette) ! Smiley fache

A le legacy code... c'est l'un des rares points où je suis content de ne pas être professionnel dans le secteur. Sur mon script précédent (l'accordéon) à un moment donné j'avais été coincé, j'avais vu que je pouvais me tirer de ce mauvais pas en jouant simplement sur la portée d'un "var". A l'arrache. Mais j'ai préféré me dire que la conception du code n'était pas bonne et j'ai revu ma manière de procéder.

En effet, je code pour le plaisir, alors je me suis dis que si je commençais à faire du code dégueu et horrible à débugger, où serait la satisfaction de ce hobby ?
Modérateur
Olivier C a écrit :

A le legacy code...


Ce n'était pas du legacy.... Le code avait 2 ans
Modérateur
je connais ce blog. J'ai lu quelques billets de lui. Celui là, je ne le connaissais pas et j'aime beaucoup. Merci pour ce partage Smiley smile

Pour du code pourri, je ne râle plus vraiment (sauf si je dois faire une charette pour livrer dans les temps).