IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Comment lire Conditions if


Sujet :

JavaScript

  1. #21
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Bonjour,

    C'est comme si... mais je me demande si c'est l'ordre exact.

    Je verrais davantage ceci :
    1) l'expression a++ vaut a avant l'incrémentation,
    2) puis a est incrémentée,
    3) puis l'expression est utilisée (ici : évaluée en tant que booléen).
    Non, cette cinétique d'exécution est fausse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let a = -1
    console.log('a: -1 =>', Boolean(a))     // true
    console.log('a++   =>', Boolean(a++))   // true
    console.log('a  =>', Boolean(a))        // false
    au départ:
    a vaut moins -1, ce qui en valeur Booléenne représente un true

    a++:
    la valeur de a inchangée est évaluée (true) pour ce que l'on veut, ici un test Booléen, mais ce pourrait aussi être une affectation ex: let b=a++ est équivalent à let b=a; a +=1 .

    si on veut que l’incrémentation de a précède il faut écrire let b=++a ( ce qui est équivalent à a +=1; let b=a;)
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  2. #22
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Je ne suis pas de cet avis.

    Ecrivons notre propre fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function Boolean2(v)
    	{
    	console.log(v,a); //-1 0
    	return Boolean(v);
    	}
     
    let a=-1;
    console.log(Boolean2(a++)); //true
    On voit que a a changé (et diffère de v) avant même de retourner le résultat de la conversion.

    Citation Envoyé par psychadelic Voir le message
    let b=a++ est équivalent à let b=a; a +=1 .
    Comme j'ai dit, l'incrémentation de a précède l'affectation de b, selon moi, ce qui ne signifie pas du tout que b prendrait la nouvelle valeur de a.
    Je refais mon exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let a=0;
    let b=-1;
    b=(a++)+(console.log(a,b),0); //1 -1
    console.log(b); //0
    Comme on le voit a vaut 1 avant que b reçoive la valeur précédente de a, soit 0.

    Encore une fois, je parle bien de l'ordre des instructions et non du fait que b prendrait la nouvelle valeur de a, ce qui n'est pas le cas, là on est d'accord.

    En fait pour moi c'est un peu comme si on faisait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function aPlusPlus()
    	{
    	const v=a;++a;return v;
    	}
    let a=0;
    let b=aPlusPlus();
     
    console.log(a,b); //1 0
    Le changement de a intervient avant celui de b bien que b reçoive la valeur précédente de a.

  3. #23
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Je ne suis pas de cet avis.

    Ecrivons notre propre fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function Boolean2(v)
    	{
    	console.log(v,a); //-1 0
    	return Boolean(v);
    	}
     
    let a=-1;
    console.log(Boolean2(a++)); //true
    On voit que a a changé (et diffère de v) avant même de retourner le résultat de la conversion.
    si on prends les choses dans l'ordre d'exécution:

    1) console.log(Boolean2(a++)); ..
    1.1 : il prépare la valeur de a pour l'envoyer à la fonction Boolean2 ( a==-1)
    1.2 : il envoie dans la pile d’exécution de l'interpréteur l'appel de la fonction Boolean2 ( avec la valeur -1 comme premier argument dans cette pile)
    1.3 : la valeur de a est incrémentée ( a==0 )
    1.4: la fonction Boolean2 commence à être exécutée par l'interpréteur

    ce que tu as écrit est équivalent à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let a = -1;
    let v = a++;
    console.log(v,a); //-1 0
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  4. #24
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Cela correspond tout à fait aux trois étapes que j'avais indiquées initialement.
    Si on fait if(a++), c'est comme si on faisait if(Boolean(a++)).
    Etape 1: l'expression a++ vaut la valeur de a avant incrémentation.
    Etape 2 : a est incrémentée.
    Etape 3 : La fonction Boolean est exécutée, certes avec un paramètre valant l'ancienne valeur de a, mais cette exécution intervient après que a ait été incrémentée.

    Comme je disais, je ne remets pas le résultat en cause, mais l'idée qu'on se fait de l'ordre d'exécution.

    Et ma phrase "On voit que a a changé (et diffère de v) avant même de retourner le résultat de la conversion." est tout à fait juste : a vaut déjà sa nouvelle valeur quand on exécute la fonction qui utilise le paramètre v qui vaut la valeur précédente de a.

    Pour l'instant, je maintiens tout ce que j'ai dit.

  5. #25
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    non, ça le fait pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function Boolean2b(v1,v2,v3,v4,v5)
      {
      console.log(v1,v2,v3,v4,v5,a); //-1 0 1 2 3 4
      return Boolean(v1);
      }
     
    let a = -1;
    console.log( Boolean2b(a++, a++, a++, a++, a++) ); //true
    avec ton explication v1, v2 , ... v5 devraient toutes avoir la même valeur à -1
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  6. #26
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Au contraire, c'est exactement conforme à ce que je dis.
    Ca renforce même.
    On voit bien que les expressions sont toutes évaluées avant l'exécution de la fonction et non après.
    C'est ce que je n'arrête pas de dire.


    Mon explication avec plusieurs expressions donnerait :
    Etape 1: la première expression a++ vaut la valeur de a avant incrémentation.
    Etape 2 : a est incrémentée.

    Etape 3 : la deuxième expression a++ vaut la valeur de a précédemment incrémentée et avant sa nouvelle incrémentation.
    Etape 4 : a est incrémentée.

    Etc.

    Etape finale : La fonction Boolean2 est exécutée, chaque paramètre correspondant à la valeur qu'avait a avant l'étape d'incrémentation correspondante (mal dit, mais on comprend j'espère).

    D'ailleurs, j'avais même mis deux exemples qui montraient qu'à l'expression suivante a avait déjà sa nouvelle valeur.

  7. #27
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    1- J'ai l'impression de voir un débat sur :

    "Qui est arrivé en premier ? L’œuf ou la poule ??"



    2- SI on revient à la problématique initiale (des comparaisons, et non des affectations) :

    A- (b==a++) :
    1. b est comparé à a
    2. PUIS a est incrémenté

    B- A contrario, (b==++a) :
    1. a est incrémenté
    2. PUIS b est comparé à (a+1) [I](on se comprend : ici, (a+1) correspond à "la valeur de a après incrémentation de 1")


    Mais, comme je l'ai déjà dit.... je peux me tromper...
    Dernière modification par Invité ; 09/07/2019 à 17h54.

  8. #28
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Je suis grandement en désaccord.

    Citation Envoyé par jreaux62 Voir le message
    A- (b==a++) :
    1. b est comparé à a
    2. PUIS a est incrémenté
    La preuve que c'est faux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let a=0;
    let b=1;
    if(b===(a++)+a)
    	{
    	console.log("oui");
    	}
    Si la comparaison avait lieu avant l'incrémentation, le test serait faux, or il est vrai.
    Cela prouve bien que a a été incrémentée avant l'évaluation finale de l'expression de droite et que la comparaison est faite après.

    Il paraît évident (ou au minimum c'est très plausible) que le simple test if(b===a++) fonctionne pareillement.

    Le principe de a++ est très certainement similaire à la fonction aPlusPlus que j'ai postée ici.

    b prend la valeur finale de l'expression.
    L'expression est évaluée progressivement.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let a=0;
    let b=(a++)+a;
    L'expression vaut d'abord 0 (cela correspond à l'évaluation de a++), puis a est incrémentée, puis l'expression vaut 1.
    b reçoit enfin la valeur finale de l'expression : 1.
    On voit bien que a n'est pas incrémentée après l'affectation de b, mais bien avant.

    De même :
    L'expression vaut d'abord 0, puis a est incrémentée, l'expression reste à 0 et b reçoit enfin la valeur finale qui est 0.
    C'est plus difficile à prouver, mais on peut raisonnablement supposer que c'est le même principe que le cas précédent (et que ça fonctionne comme ma fonction aPlusPlus).

    Bon j'espère que c'est enfin clair.
    Je n'ai pas réagi sur tout, je pourrai apporter des précisions sur le reste s'il y a encore des doutes.

  9. #29
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Salut,

    Je crois que nous sommes tous plus ou moins d'accord...

    Citation Envoyé par Loralina Voir le message
    Citation Envoyé par Beginner. Voir le message
    a++ est donc bien exécutée mais après l'évaluation de la condition
    C'est comme si... mais je me demande si c'est l'ordre exact.

    Je verrais davantage ceci :
    1) l'expression a++ vaut a avant l'incrémentation,
    2) puis a est incrémentée,
    3) puis l'expression est utilisée (ici : évaluée en tant que booléen).

    Si on a plusieurs expressions, on voit que l'incrémentation a lieu avant l'évaluation complète en tant que booléen : si a=0, alors console.log(Boolean(a++ || (console.log(a),a))) affichera 1 et true.
    Alors je rappelle que ma phrase concernait cette instruction : if (a || a++).

    Alors oui je pense qu'il n'est pas faux de dire que a++ est exécutée après l'évaluation de la condition mais c'est vrai que c'est le cas parce qu'il se trouve que a++ est la dernière opérande évaluée de la condition... C'est donc un cas particulier.

    Vous avez raison de pointer ce problème car c'est vrai que si a++ n'avait pas été la dernière opérande évaluée ma phrase aurait été fausse...

    En fait si j'ai bien compris, ce qui se passe c'est que chaque opérande est évaluée de gauche à droite... Si par exemple on a trois opérandes comme ceci : a && a++ && (b=a) dans le code suivant :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var a = -1, b = undefined ; 
    a && a++ && (b=a)
    console.log("a : " + a, "b : " + b); // a : 0 b : 0

    Ici la deuxième opérande c'est a++ alors là en effet il ne serait pas correcte de dire que l'incrémentation de a (a++) est exécutée après l'évaluation (complète) de la condition... Mais cette fois je dirais plutôt que l'incrémentation de a (a++) est exécutée après l'évaluation de la seconde opérande de la condition...

    La preuve c'est que la troisième opérande "(b=a)" est bien évaluée et que l'on a : a = 0 et b = 0 ---> quand la deuxième opérande est évaluée a++ vaut -1 (et non 0, si a++ valait 0 la troisième opérande ne serait pas évaluée) et quand la troisième est évaluée a vaut 0.

    Ainsi au moment où la troisième opérande est évaluée l'incrémentation de a a déjà eu lieu, elle a donc eut lieu avant l'évaluation complète de la condition...

    Je pense que nous sommes d’accord sur ce point à moins d’avoir mal compris ?

    Citation Envoyé par Loralina Voir le message
    Dans le même genre, on lit souvent que si on écrit :
    alors b vaut 0 puis a est incrémentée, comme si on avait écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var a=0;
    var b=a;
    ++a;
    Mais cela correspond-il à l'ordre réel ?
    Pour moi oui c'est équivalent mais en fait là aussi c'est parce qu'il n'y a qu'une seule opérande (a++) utilisant la variable a (a++ est la première et dernière opérande).

    Citation Envoyé par Loralina Voir le message
    Cet exemple permet d'en douter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var a=0;
    var b=(a++)+0;
    Pour moi, a vaut 1 avant l'addition et donc avant que b ne prenne sa valeur.
    On est d'accord qu’après l'affectation a vaut 1 et que b vaut 0 après il est bien possible qu’après l'évaluation de la première opérande (a++) de l'addition que la valeur de la variable a soit 1 mais ici cela n'a pas d'importance car la variable a n'est plus utilisée...

    Mais bon je crois que je vois où vous voulez en venir... D'où les exemples suivants :

    Citation Envoyé par Loralina Voir le message
    Pour moi, a vaut 1 avant l'addition et donc avant que b ne prenne sa valeur.
    En effet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function zero(){console.log(a,b);return 0;}
    var a=0;
    var b=-1;
    b=(a++)+zero();
    On voit que b n'a pas encore changé de valeur et vaut donc encore -1 alors que a est déjà passé à 1.

    De même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var a=0;
    var b=(a++)+a; //b=1
    Oui nous sommes d'accord, cette fois l'addition a deux opérandes et la deuxième utilise la variable a or au moment où la deuxième opérande est évaluée la variable a a déjà été incrémentée (lors de l'évaluation de la première opérande et c'est la valeur incrémentée de a qui est utilisée lors de l'évaluation de la seconde opérande).

    C'est le même principe que pour les conditions, chaque opérande est évaluée de gauche à droite...

    Merci pour le rappel (ou la découverte), je n'y avais pas trop pensé...

  10. #30
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Re-Salut,

    Citation Envoyé par Loralina Voir le message
    Je suis grandement en désaccord.
    Pour moi vous avez tous les deux raisons et le problème vient du fait que vous comparez des expressions à une seule opérande avec des expressions avec plusieurs opérandes...

    Citation Envoyé par Loralina Voir le message
    Citation Envoyé par jreaux62 Voir le message
    A- (b==a++) :
    1. b est comparé à a
    2. PUIS a est incrémenté
    La preuve que c'est faux :
    Pour moi dans ce cas, ce n'est pas faux (du moins en apparence) de dire que la comparaison a lieu avant l'incrémentation (en ce sens que c'est bien la valeur de a avant son incrémentation qui est comparée à b) mais c'est vrai (comme déjà expliqué) que c'est le cas parce qu'il n'y a qu'une seule opérande à savoir a++.

    C'est vrai que ce n'est qu'une apparence mais expliqué comme ça pour ce cas précis c'est plus simple à comprendre après la règle complète c'est qu'il faut évaluer toutes les opérandes de gauche à droite avant de faire la comparaison mais ici on est dans un cas particulier où l'incrémentation de a est la seule opérande donc on peut dire pour faire simple que l'incrémentation a lieu après la comparaison.

    Si il y avait une autre opérande après a++ comme dans l'exemple que vous donnez après il en serait autrement car alors il faudrait évaluer cette autre opérande pour pouvoir faire la comparaison...

    Citation Envoyé par Loralina Voir le message
    La preuve que c'est faux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let a=0;
    let b=1;
    if(b===(a++)+a)
        {
        console.log("oui");
        }
    Si la comparaison avait lieu avant l'incrémentation, le test serait faux, or il est vrai.
    Cela prouve bien que a a été incrémentée avant l'évaluation finale de l'expression de droite et que la comparaison est faite après.
    Ben cette fois l'expression (a++)+a a deux opérandes (a++) et a alors oui cette fois la comparaison a lieu après l'incrémentation ce qui est normal car il y a la deuxième opérande a évaluée avant de pouvoir faire la comparaison.

    Mais c'est vrai encore fois que c'est un point à faire remarquer, c'est une subtilité qui a son importance...

  11. #31
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Merci pour ce retour Beginner..
    On est déjà plus sur la même longueur d'onde.

    Juste une réaction :
    Citation Envoyé par Beginner. Voir le message
    après il est bien possible qu’après l'évaluation de la première opérande (a++) de l'addition que la valeur de la variable a soit 1 mais ici cela n'a pas d'importance car la variable a n'est plus utilisée...
    Je pense que cet exemple tend à le confirmer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let b=(a++)+(console.log(a),0);
    Ensuite, mon hypothèse privilégiée est que la mécanique va être la même pour ces deux cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //cas 1
    let a=0;
    let b=(a++)+0;
    //b=0
     
    //cas 2
    let a=0;
    let b=(a++);
    //b=0
    Dans le cas 1), l'incrémentation a lieu avant l'affectation comme tend à le confirmer l'exemple précédent.
    Certes, il n'est pas interdit de penser que dans le cas 2), l'incrémentation est exécutée après l'affectation, mais je trouverais étonnant qu'il y ait une gestion particulière de ce cas.

    J'ajoute :
    C'est comme avec return a++; : comme il n'y a pas d'instructions après un return, je pense que l'incrémentation a lieu avant le retour, même si c'est la valeur avant incrémentation qui est retournée (ça correspondrait aux étapes dont je parlais : évaluation de l'expression, incrémentation, utilisation de l'expression qui est retournée).
    Certains imagineront peut-être qu'il y a une instruction en interne après le return pour incrémenter a, mais ça me surprendrait un peu.

  12. #32
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Je suis grandement en désaccord.
    Citation Envoyé par jreaux62
    A- (b==a++) :
    1- b est comparé à a
    2- PUIS a est incrémenté
    La preuve que c'est faux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let a=0;
    let b=1;
    if(b===(a++)+a)
    	{
    	console.log("oui");
    	}
    Ce n'est pas du tout le même exemple.

    pour faire plus simple en test je propose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // test 1:
    let a=0, b=1; console.log('test 1: (b==a++)? ------->', (b==a++) ? 'égalité': 'différents' ) 
     
    // test 2
       a=0; b=1;  console.log('test 2: (b===(a++)+a)? -->', (b===(a++)+a) ? 'égalité': 'différents' ) 
     
    // test 3.1
       a=0; b=1;  console.log('test 3.1: (a++)+0  -->', (a++)+0 )
     
    // test 3.2
       a=0; b=1;  console.log('test 3.2: (a++)+a  -->', (a++)+a )
    résultats :
    • test 1: (b==a++)? -------> différents
    • test 2: (b===(a++)+a)? --> égalité
    • test 3.1: (a++)+0 --> 0
    • test 3.2: (a++)+a --> 1

    Dans le cas du premier, test 1 , cela se passe comme jreaux62 le décrit : l'interpréteur JS test l'égalité de a et b; PUIS incrémente a.
    autrement dit l'incrémentation de a ne concerne pas le test

    dans le cas du second, test 2, b est comparé à une expression calculée:
    l'interpréteur JS fait une évaluation de l' expression (a++)+a
    ce qui revient a faire 0 +1 (et non 1+0)
    comme on peut le constater dans les tests 3.1 et 3.1

    cette expression calculée est ensuite comparée avec la valeur de b
    (elles sont toutes les 2 à 1, donc égales)
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  13. #33
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Ensuite, mon hypothèse privilégiée est que la mécanique va être la même pour ces deux cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //cas 1
    let a=0;
    let b=(a++)+0;
    //b=0
     
    //cas 2
    let a=0;
    let b=(a++);
    //b=0
    Dans le cas 1), l'incrémentation a lieu avant l'affectation comme tend à le confirmer l'exemple précédent.
    Le problème c'est qu'on pourrait mal le comprendre, on pourrait comprendre que puisque l'incrémentation a lieu avant l'affectation alors b devrait valoir 1 or ce n'est pas le cas il vaut 0.

    Mais en fait tout va bien si on ne confond pas l'incrémentation avec la valeur de la première opérande... L'incrémentation a lieu à l'étape 2 ci-dessous mais ce n'est pas cette valeur incrémentée qui est utilisée à l'étape 4 ci-dessous mais la valeur (évaluée à l'étape 1) de la première opérande.

    C'est pour ça je pense qu'il y a l'explication de ce qui se passe en apparence (qui est plus simple à comprendre) et l'explication du fonctionnement interne, je crois que le deuxième peut embrouiller les débutants... Mais c'est vrai que lorsque l'on a affaire à plusieurs opérandes on n'a pas le choix, il faut expliquer un minimum le mécanisme interne...

    Peut-être que le plus simple c'est d'en revenir à la règle comme quoi toutes les opérandes doivent être évaluées de gauche à droite avant de faire l’affection ou la comparaison ou autre...

    Par exemple dans le cas 1 :

    1- On évalue la première opérande : a++ (a++ vaut 0 au moment de l’évaluation de la première opérande).
    2- L'incrémentation a lieu avant l’évaluation de la deuxième opérande ---> a passe à 1
    3- On évalue la deuxième opérande 0 (0 vaut 0).
    4- On additionne la valeur de la première opérande évaluée à 0 à l'étape 1 (et non la valeur incrémentée de a qui vaut 1) à la valeur de la deuxième opérande évaluée à 0 à l'étape 3.
    5- Et en enfin on affecte la somme (0+0) à b.

    On a donc b= 0 et a = 1.
    La variable a vaut 1 à cause de l'étape deux mais sa valeur incrémentée n'est pas utilisée et c'est ça qu'il faut bien repérer pour comprendre que b vaut 0 (et non 1) après l’affection.

    C'est plus compliqué à comprendre ou du moins plus long à expliquer et ici il n'y a pas beaucoup d’intérêt car la variable a n'est pas utilisée après la première opérande.

    Citation Envoyé par Loralina Voir le message
    Certes, il n'est pas interdit de penser que dans le cas 2), l'incrémentation est exécutée après l'affectation, mais je trouverais étonnant qu'il y ait une gestion particulière de ce cas.
    Oui cela ne m'étonnerait pas que la mécanique interne soit la même après on dit que l'incrémentation est exécutée après l'affectation pour faire simple et pour être compris par ceux qui ne connaissent pas le fonctionnement interne ou qui ont du mal à le comprendre.

    Mais bien sûr ce n'est pas toujours possible de s'en tenir à cette explication simple, on aura besoin de comprendre le mécanisme interne dans le cas où on a plusieurs opérandes utilisant la variable a...

    C'est donc une bonne chose d'avoir soulevé le problème...

  14. #34
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Certes, il n'est pas interdit de penser que dans le cas 2), l'incrémentation est exécutée après l'affectation, mais je trouverais étonnant qu'il y ait une gestion particulière de ce cas.
    Soit étonné parce que c'est justement le cas.
    Tout langage évolué est avant tout transformé en assembleur.

    la simple affectation : let A = -1 correspond à:
    prendre un espace mémoire pour stocker une valeur numérique en lui mettant la valeur -1.
    je te passe la cuisine du système d'adressage permettant de mettre en relation le string contenant le nom de la variable, de l'attribution du lien entre ces 2 éléments, de la gestion d'une table d'adressage et autres joyeusetés à coder.

    quand par la suite du code JS on retrouve B = A l'interpréteur JS fait simplement une copie de mémoire à mémoire de la valeur présente à l'adresse de la variable A pour la copier à l'adresse de la variable B
    (grosso modo, parce qu'il y a en plus des vérifications de typage pour savoir s'il faut affecter une nouvelle portion de mémoire dans le cas d'un changement de type, entres autres histoires)

    Dans le cas d'un B = A++ c'est la même opération, sauf qu'ensuite il place la valeur de A dans un registre du processeur sur lequel il donne l'ordre d'éffectuer une incrémentation pour ensuite récupérer cette valeur pour la replacer à l'adresse mémoire de la variable A.

    les processeurs actuels savent effectuer des opérations de mémoire à mémoire, mais il est plus probable que dans le cas présent il fasse la copie de la variable A dans un registre (parce qu'il à détecté qu'il s'agit d'un entier pouvant être mis en registre) puis il fait la copie du registre à l'adresse de la variable B.
    Puis, si l'on est dans le cas d'une incrémentation "postérieure" il la réalise dans le registre pour être ensuite recopiée à l'adresse de la variable A.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  15. #35
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 957
    Points : 44 121
    Points
    44 121
    Par défaut
    Bonjour,
    il y a des noeuds au cerveau en perspective

    Que dit ECMAScript® Language Specification, en à peine simplifié

    ++ en prefix, l'incrémentation est faite avant l'utilisation de la valeur de la variable, Return newValue.
    ++ en postfix, l'incrémentation est faite après l'utilisation de la valeur de la variable, Return oldValue.
    C'est la même chose pour l'opérateur --.

    Test simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var a = 0;
    if (a++) {
      console.log("if :", a);
    }
    else {
      console.log("else :", a);  // > "else :" 1
    }
    // on recommence
    a = 0;
    if (a++ || a) {
      console.log("if :", a);    // > "if :" 1
    }
    else {
      console.log("else :", a);
    }
    Ceci est aussi valable, il n'y a pas de raison, pour le cas du return évoqué par Loralina.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function getA(param){
      let a = param;
      return a++;
    }
    console.log("getA :", getA(5)); // > "getA :" 5
    Ressource :
    Postfix Increment Operator

  16. #36
    Invité
    Invité(e)
    Par défaut
    @NoSmoking
    Il manque un 3ème test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // test 3
    a = 0;
    if (a || a++) {
      console.log("3- if :", a);
    } else {
      console.log("3- else :", a);    // > "3- else :" 1
    }
    Par conséquent : (a++ || a) N'EST PAS équivalent à (a || a++) !!

    La raison a été donnée plusieurs fois : le code est traité de gauche à droite.

    1- (a++ || a) :
    • a vaut 0
    • a est incrémenté
    • a vaut 1
    • ENFIN, la condition est évaluée : (a++ || a) donne (0 || 1) -> true

    2- (a || a++) :
    • a vaut 0
    • a vaut 0
    • ICI, la condition est évaluée : (a || a++) donne (0 || 0) -> false
    • Et seulement APRES, a est incrémenté : a vaut 1


    3- autre test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    let a,b;
    // test 1
    a=0;
    b=1;
    if(b===(a++)+a)
    {
      console.log("test 1 : oui",a,b);
    } else {
      console.log("test 1 : non",a,b);
    }
    // test 2
    a=0;
    b=1;
    if(b===a+(a++))
    {
      console.log("test 2 : oui",a,b);
    } else {
      console.log("test 2 : non",a,b);
    }
    On obtient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    test 1 : oui 1 1
    test 2 : non 1 1
    Dernière modification par Invité ; 09/07/2019 à 17h53.

  17. #37
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Bonjour,
    Beginner., je suis d'accord.

    psychadelic :
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    <script>
    //https://gist.github.com/adriengibrat/b0ee333dc1b058a22b66
    /**
     * Object.prototype.watch polyfill
     * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch
     *
     * Known limitations:
     * - `delete object[property]` will remove the watchpoint
     *
     * Based on Eli Grey gist https://gist.github.com/eligrey/384583
     * Impovements based on Xose Lluis gist https://gist.github.com/XoseLluis/4750176
     * This version is optimized for minification
     *
     * WTFPL.
     * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
     */
     
    (function (Object, descriptor) {
      var prototype = Object.prototype,
        defineProperty = Object.defineProperty,
        getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
        enumerable = 'enumerable';
      // object.watch
      if (!prototype.watch) {
        descriptor.value = function (property, handler) {
          var
            descriptor = getOwnPropertyDescriptor(this, property),
            _value = descriptor.value,
            getter = descriptor.get || function () {
              return _value;
            },
            setter = function (value) {
              _value = handler.call(this, property, _value, value);
              if (setter._set) {
                setter._set.call(this, _value);
              }
              return _value;
            }
          ;
          setter._set = descriptor.set; // backup old setter
          if (descriptor.configurable && // can't watch constants
            descriptor.writable !== false) { // don't watch readonly
            defineProperty(this, property, {
              get: getter,
              set: setter,
              enumerable: descriptor[enumerable],
              configurable: true
            });
          }
        };
        defineProperty(prototype, 'watch', descriptor);
        // object.unwatch
        descriptor.value = function (property) {
          var descriptor = getOwnPropertyDescriptor(this, property);
          if (descriptor.set && descriptor.set.hasOwnProperty('_set')) {
            defineProperty(this, property, descriptor.set._set ? {
              get: descriptor.get,
              set: descriptor.set._set,
              enumerable: descriptor[enumerable],
              configurable: true
            } : {
              value: this[property],
              enumerable: descriptor[enumerable],
              configurable: true,
              writable: true
            });
          }
        };
        defineProperty(prototype, 'unwatch', descriptor);
      }
    })(Object, {enumerable: false, configurable: true, writable: false});
     
     
    //https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/watch
    function watchVar(id, oldval, newval) {
    	console.log("o." + id + " a été modifiée de " + oldval + " en " + newval);
    	return newval;
    	}
     
    var o={a:0,b:null};
    o.watch("a",watchVar);
    o.watch("b",watchVar);
    o.b=o.a++;
     
    //o.a a été modifiée de 0 en 1
    //o.b a été modifiée de null en 0
    </script>
    Pour moi, cela montre que la post incrémentation est exécutée avant l'affectation (et qu'il n'y a donc pas de gestion particulière du cas où il n'y a rien après le a++).
    Et cela ne s'oppose en rien au fait que b va recevoir la valeur avant incrémentation.

    NoSmoking :
    Citation Envoyé par NoSmoking Voir le message
    ++ en postfix, l'incrémentation est faite après l'utilisation de la valeur de la variable, Return oldValue.
    Oui, mais de quelle utilisation est-il question ? Et qui reçoit oldValue ?
    Quand on fait b=(a++)+1, l'utilisation correspond à l'évaluation progressive de l'expression, c'est l'expression (j'ajoute (13h11) : je devrais plutôt dire la variable interne associée ou du moins l'évaluation de l'expression) qui reçoit oldValue, on n'est pas encore à l'étape de l'affectation à b.
    Maintenant, si on a juste b=a++, c'est pareil comme le montre le script que je viens de mettre, l'expression reçoit oldValue, a est incrémentée, et enfin l'affectation de l'expression à b est faite.

    C'est le même principe pour les comparaisons et le return dans une fonction (le retour de l'expression finale s'effectue après toutes les post incrémentations).

  18. #38
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    On obtient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    test 1 : oui 1 1
    test 2 : non 1 1
    Est-ce encore nécessaire de l'expliquer * ??
    * l'explication a déjà été donnée plusieurs fois
    Ce résultat est parfaitement en accord avec tout ce que j'ai écrit.

    if(b===a+(a++)) :
    Etape 1 : l'expression de droite est évaluée progressivement.
    Elle vaut 0+0.
    Etape 2 : a est incrémentée.
    Etape 3 : Il n'y a plus rien après cette incrémentation, l'expression reste donc à 0.
    Etape 4 : La comparaison est enfin faite : b===0 ? non donc on passe dans le else.

    Le principe est le même avec if(b===(a++)+a).
    Dans les deux cas, la comparaison aura lieu après toutes les post-incrémentations.

    Le code que j'ai publié au-dessus va quand même dans ce sens.

  19. #39
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    Que dit ECMAScript® Language Specification, en à peine simplifié
    Et bien justement je suis allée voir la version pas simplifiée et pour moi ça confirme ce que j'ai dit, et même en pire : l'incrémentation est faite encore plus en amont (je le supposais un peu).
    En réalité c'est comparable à ma fonction aPlusPlus.

    Voici le lien que je viens de consulter : Postfix Increment Operator.
    (J'ajoute (10/7, 9h40) : NoSmoking avait déjà mis un lien.)

    Comme on peut le voir : Let oldValue, Let newValue et PutValue(lhs, newValue), ces trois choses sont réalisées avant Return oldValue.
    C'est bien ce que je faisais dans ma fonction aPlusPlus (en simplifié).

    Donc quand on fait if(b===a+(a++)) :
    (J'ajoute (10/7, 9h40) : je n'en ai pas parlé, mais la première étape est évidemment l'évaluation de b.)
    Etape 1 : l'expression de droite vaut d'abord 0.
    Etape 2 : on arrive au deuxième terme de l'addition : la valeur actuelle de a est mémorisée, a est incrémentée, la valeur retournée est la valeur mémorisée, soit 0.
    Etape 3 : on additionne ce 0 à la valeur actuelle de l'expression.
    Etape 4 : La comparaison est enfin faite : b===0 ? non donc on passe dans le else.

    De même quand on écrit : b=a++;, c'est pareil que faire b=aPlusPlus();, l'incrémentation de a aura bien lieu avant l'affectation à b qui aura pourtant l'ancienne valeur de a.

    Citation Envoyé par Beginner. Voir le message
    Oui cela ne m'étonnerait pas que la mécanique interne soit la même après on dit que l'incrémentation est exécutée après l'affectation pour faire simple et pour être compris par ceux qui ne connaissent pas le fonctionnement interne ou qui ont du mal à le comprendre.
    Oui, mais je trouve ça dommage car au final presque tout le monde a une fausse idée de l'ordre des opérations.

  20. #40
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    La seule chose qui nous mettrait vraiment d'accord, ce serait d'aller retrouver les sources de l'interpréteur et d'ensuite de décortiquer le code en assembleur x86 pour voir ou, quand comment il place cette incrémentation.
    https://fr.wikipedia.org/wiki/Moteur_JavaScript
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

Discussions similaires

  1. Comment lire un fichier DB en cours d'utilisation par 1 autr
    Par jbat dans le forum Bases de données
    Réponses: 4
    Dernier message: 12/03/2004, 11h06
  2. Comment lire un fichier image
    Par Charlemagne dans le forum DirectX
    Réponses: 9
    Dernier message: 12/03/2004, 00h22
  3. [Debutant] Comment lire la taille d'un fichier binaire ?
    Par Invité dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 18/12/2003, 19h20
  4. Réponses: 2
    Dernier message: 06/12/2002, 07h50
  5. Réponses: 5
    Dernier message: 20/08/2002, 18h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo