11485 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous

En essayant de mettre de l'ordre dans mes fichiers JavaScript, je me rends compte que le même nom est parfois utilisé dans plusieurs fichiers, ce qui ne devrait pas être le cas.
Cependant je constate que ça a l'air de marcher... ce qui me semble assez aberrant.

Par exemple j'ai la définition suivante dans le fichier "centrale.js"
function Tile(url, img, frTitle, enTitle) {
    .....
    .....
}

et dans le fichier "tileList.js"
function Tile(data) {
    .....
    .....
}

et ces deux fichiers sont référencés dans la page "centrale.htm"
Et pourtant, selon toutes les apparences, les appels de ces fonctions (en fait des définition d'objets) se produisent sans encombre et donnent les résultats espérés, comme s'il existait une "portée" des définitions de fonctions: si j'appelle une fonction dans un fichier js et qu'elle est définie dans ce fichier, c'est celle là qui est appelée, même si la même fonction est définie dans un autre fichier js.

Je vais bien entendu modifier les noms de fonctions pour éviter cette situation, mais j'aimerais savoir ce qu'il en est réellement.
Modifié par PapyJP (05 Apr 2017 - 13:26)
PapyJP a écrit :
Bonjour à tous
En essayant de mettre de l'ordre dans mes fichiers JavaScript, je me rends compte que le même nom est parfois utilisé dans plusieurs fichiers, ce qui ne devrait pas être le cas.
Cependant je constate que ça a l'air de marcher... ce qui me semble assez aberrant.
Par exemple j'ai la définition suivante dans le fichier "centrale.js"
function Tile(url, img, frTitle, enTitle) {
    .....
    .....
}

et dans le fichier "tileList.js"
function Tile(data) {
    .....
    .....
}

et ces deux fichiers sont référencés dans la page "centrale.htm"
Et pourtant, selon toutes les apparences, les appels de ces fonctions (en fait des définition d'objets) se produisent sans encombre et donnent les résultats espérés, comme s'il existait une "portée" des définitions de fonctions: si j'appelle une fonction dans un fichier js et qu'elle est définie dans ce fichier, c'est celle là qui est appelée, même si la même fonction est définie dans un autre fichier js.
Je vais bien entendu modifier les noms de fonctions pour éviter cette situation, mais j'aimerais savoir ce qu'il en est réellement.

En fait, ce comportement est normal dans la mesure où la liste des paramètres passés à la fonction homonyme est différente...
C'est un principe POO bien connu en Java, par exemple, ainsi que dans d'autres langages de programmation, permettant d'avoir plusieurs versions d'une même méthode (fonction offerte par un objet), différenciées selon les besoins.
Par exemple, pour mon générateur, j'ai un objet style CSS pour lequel les attributs de type couleur disposent des méthodes :
newInstance(final Color color) { ... }
newInstance(final int red,final int green,final int blue,final int alpha) { ... }
newInstance(final int red,final int green,final int blue) { ... }
newInstance(final String keyword) { ... }

C'est une facilité d'appel de méthode, puisqu'on appelle ensuite celle qui correspond le mieux aux infos dont on dispose à un instant T.
Modifié par sepecat (06 Apr 2017 - 06:11)
Javascript ne permet pas ce que tu dis Sepecat


function Test(color, size) {
  
  window.alert(color + ' ' + size)
  
}

function Test(color) {
  
  window.alert(color)
  
}

Test('blue', '25'); //Affiche blue


Je pense plus à une histoire de scope ou alors les fonctions sont appelées/déclarées dans le bon ordre et donc cela fonctionne quand même.
Bonjour à tous et merci pour vos réponses

En ce qui concerne la réponse de Sepecat, c'est effectivement une fonctionnalité intéressante de certains langages de POO, mais en JavaScript (comme en PHP également) les données ne sont pas typées, donc je ne vois pas comment cela pourrait être le cas

Avant de nettoyer le code, j'ai fait de nombreux tests avec trace (console.log) et je crois finalement avoir compris: il s'agit de l'ordre dans lequel les fichiers js sont chargés, à savoir
1) le premier fichier se charge et certains scripts sont exécutés en appelant la version 1 de la fonction
2) le deuxième fichier de script est ensuite inséré dynamiquement, la version2 de la fonction vient écraser la précédente version, et les scripts qui appellent la fonction appellent donc la version2
C'est donc la réponse de bzh qui me semble la bonne.

Je ne recommande évidemment à personne de jouer au petit jeu qui consisterait à utiliser volontairement cet effet de bord: dans ce cas précis, l'ordre de chargement est assuré, puisque ce sont les script du premier fichier qui génèrent le chargement dynamique du second, et la version1 de la fonction n'est plus utilisée. Mais il suffirait d'une petite modification dans le programme pour que cet effet de bord disparaisse.
Modifié par PapyJP (10 Apr 2017 - 10:45)
bzh a écrit :
Javascript ne permet pas ce que tu dis Sepecat


function Test(color, size) {
  
  window.alert(color + ' ' + size)
  
}

function Test(color) {
  
  window.alert(color)
  
}

Test('blue', '25'); //Affiche blue


Je pense plus à une histoire de scope ou alors les fonctions sont appelées/déclarées dans le bon ordre et donc cela fonctionne quand même.

C'est bien pourquoi j'ai toujours considéré javascript, et plus généralement les langages faiblement typés, comme du "bricolage".
Une fonction dotée d'arguments non typés reste, par exéprience, une source chronique d'erreurs dans la mesure où rien n'est vérifié en amont.
Pouvoir passer tout et son contraire est, certes, une facilité d'écriture en soi, mais à un moment ou un autre il faut choisir entre sécurité / maintenance d'un côté, laxisme de l'autre.
J'ai eu l'occasion de le mentionner à plusieurs reprises sur ce forum, javascript n'est pas, et de loin, le langage que j'utilise en environnement pro (Java / C#), mais j'entends bien l'intégrer dans mon générateur web, puisqu'il est, de fait, incontournable dans cet espace.
L'avantage du générateur est toutefois intéressant, puisqu'il va manipuler des types Java parfaitement définis, à partir desquels seront construites les fonctions javascripts nécessaires.
Un champ / variable déclaré de type entier dans une classe Java gardera ce typage "logique" lorsqu'il sera manipulé et sérialisé tout au long de la création du site web.
Effectivement, le typage faible va de paire avec l'impossibilité des mécanismes de surcharge de méthodes.

Par contre je ne suis pas tout à fait d'accord en ce qui concerne la sécurité du code. JavaScript est en retard sur ce point, mais PHP et python entres autres langages ont comblé certaines failles en donnant la possibilité de spécifier le type des paramètres attendus.

PHP:

function toto (int $tata, array $tutu, MaClasse $titi) { 
... 
}


Python:

def toto (tata: int, tutu: list, titi: MaClasse):
    ...


Sans même chercher, je ne doute pas une seconde que des idées similaires ont, à défaut d'avoir été acceptées, au moins déjà été évoquées pour ECMAScript 2017 ou 2018. Mème si la vérification n'est pas forcément stricte (pas par défaut en python pour le moment), malgré tout, ça aide pour lire le code.


Maintneant pour répondre à la question initiale et pour être bin complet, en JavaScript côté serveur avec Node.js, il existe bien une portée distincte par fichier, mais pas pour JavaScript sur le navigateur.
Donc à moins de créer artificiellement un bloc hermétique avec une fonction appelée immédiatement, avoir le même nom dans plusieurs fichiers distincts revient clairement à jouer avec le feu.

Dans le cas que tu exposes, ça marche effectivement uniquement parce que les fichiers sont appelés dans le bon ordre et parce que le navigateur ne peut pas appliquer l'effet de hoisting entre plusieurs fichiers chargés successivement, de fait créant deux portées distinctes.

Par contre tu as bien raison de ne pas te fier à ça... c'est très piégeant.

Fichier 1

function tata () {
alert('coucou');
}

function toto () {
window.tata();
}


Fichier 2

function tata () {
alert('salut');
}

function titi () {
tata();
}


Fichier 3

toto();
titi();


Bonne migraine.
Modifié par QuentinC (09 Apr 2017 - 21:00)