Plusieurs « if » ou une combinaison « if/else if » avec « return » ?

Le problème exposé dans ce sujet a été résolu.

Bonsoir,

Voici un morceau d’un fichier que je viens de finir d’écrire :

exec(channel) {
    if (channel.type === 'text') {
        return channel.guild.channels.get(config.defaultChannel).send(i18n.t('events:channel.create.text', { channel: channel, interpolation: { escapeValue: false }}));
    }
    if (channel.type === 'voice') {
        return channel.guild.channels.get(config.defaultChannel).send(i18n.t('events:channel.create.voice', { channel: `**${channel}**`, interpolation: { escapeValue: false }}));
    }
    if (channel.type === 'category') {
        return channel.guild.channels.get(config.defaultChannel).send(i18n.t('events:channel.create.category', { category: `**${channel.name}**`}));
    }
}

Le contenu des if n’est pas important. En gros, exec() s’exécute à la création d’un nouveau channel. En fonction de son type, un message différent est envoyé. Je me demandais si, au niveau pratique ainsi qu’au niveau performance, il valait mieux faire suivre trois if ou bien un if suivi de deux else if.

Merci d’avance :) .

Pour ce genre de cas, un switch est certainement ce qu’il y a de plus intéressant.
Tant niveau lisibilité que performance.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

+0 -0

Oh, un utilisateur d’i18 nexts on dirait bien :D

Pour répondre à ta question, c’est avant tout une question de programmation générale et non quelque chose de spécifique à JS.

Imaginons que tu veux te faire des œufs aux plats et que tu veux le faire avec 2 œufs. Tu vas te poser les questions suivantes :

  • si je n’ai pas d’œuf, alors j’en rajoute 2
  • sinon, si j’ai un œuf, alors j’en rajoute 1
  • sinon, c’est ok, je peux passer à la suite

Ce sont des « états » (avoir qu’un œuf, avoir 2 œufs, etc.) qui ne pourront jamais arriver au même moment. En effet, tu ne peux pas avoir 1 œuf et 2 œufs en même temps (sauf si tu le voies en mode décomposition).

Du coup dans ce genre de cas là, où les « états » ne peuvent arriver au même moment, tu dois utiliser les instructions du langage qui permettent de gérer cela.

En JS tu à bien sûr le else if, mais également le switch comme l’a mentionné @ache.

+0 -0

Moi generalement je ne fais pas de return dans les test :

exec(channel) {

    options = {}
    
    if (channel.type === 'text') {
        options = { channel: channel, interpolation: { escapeValue: false }};
    }
    if (channel.type === 'voice') {
        options = { channel: `**${channel}**`, interpolation: { escapeValue: false }}
    }
    if (channel.type === 'category') {
        options = { category: `**${channel.name}**`}
    }
    
    event = 'events:channel.create.' + channel.type;
    return channel.guild.channels.get(config.defaultChannel).send(i18n.t(event, options));
}

Oh, un utilisateur d’i18 nexts on dirait bien :D

Heziode

C’est en effet cette bibliothèque ! J’ai longtemps hésité à sauter le pas et finalement, je trouve cela fantastique ^^ !

@Zérotisme : Au niveau performance, l’avantage de mettre le return dans le if, c’est que ça interromp la fonction quand la première condition est remplie. Ça fait gagner un peu de temps d’exécution.

Phigger

C’est en effet l’objectif de mes return Dans le cas d’un code qui retourne quelque chose dans chaque bloc de la condition, on m’a conseillé de faire plusieurs bloc if ou ne pas mettre de else. Par exemple :

const age = 33;
if (estMajeur(age) {
    console.log('Santé !');
}

const estMajeur = age => {
    if (age > 18) {
        return true;
    }
    return false;
}

En fait, la problématique revient à la simplification du code où à l’optimisation de l’exécution. La correction de @Zérotisme est bien plus clair que de répéter la méthode à rallonge qui permet d’envoyer un message. Pour le coup, je ne sais pas du tout quel choix faire :euh: .

Je vais penser au switch que je n’utilise pas assez à cause de ce qui m’a été dit lors de mon apprentissage : proscrire. Malgré le fait de savoir que c’est trop extrême, je n’arrive pas à y penser. Dans tous les cas, si je pars sur le switch, il faut que je réfléchisse à ce qui est à l’intérieur. Hormis si break jouera d’une certaine façon le rôle de return ?

Voilà le résultat final que j’obtiens :

let options;

switch (channel.type) {
    case 'text':
        options = { channel: channel, interpolation: { escapeValue: false }};
        break;
    case 'voice':
        options = { channel: `**${channel}**`, interpolation: { escapeValue: false }}
        break;
    case 'category':
        options = { category: `**${channel.name}**` }
}

return channel.guild.channels.get(config.defaultChannel).send(i18n.t(`events:channel.create.${channel.type}`, options));

Est-ce la meilleure manière que je puisse écrire cette conditions ?

Moi j’approuve.

Tu as oublié le break dans le cas du "category" même si ce n’est pas vraiment utile. Tu ne gère pas les erreurs ? Si on passe autre chose que "text", "voice" ou "category" que va-t-il ce passer ?

Connaissant i18next, il va simplement t’afficher la clé "events:channel.create.foo" par exemple. ^^

Après, si tu veux un truc « très » optimisé, le mieux c’est de faire des mesures avec d’autres façon de faire.

+1 -0

J’ai omis exprès le dernier break car la suite doit être exécuté quoi qu’il arrive. Il en est de même pour l’absence de default car channel.type ne peut prendre que les trois valeurs que tu vois ci-dessus.

Par contre, bizarrement, il y a un autre cas où j’utilise une variable directement dans i18n.t() qui retourne une erreur mais le code de ma précédente réponse fonctionne à merveille.

Mon objectif est que cela soit le plus performant possible tout en étant lisible pour un humain (autre ou moi dans le futur). Je pense garder comme ça !

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte