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 :

JavaScript pour les Jedis, épisode I : au cœur des fonctions [Tutoriel]


Sujet :

JavaScript

  1. #1
    Expert éminent sénior

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Points : 79 915
    Points
    79 915
    Par défaut JavaScript pour les Jedis, épisode I : au cœur des fonctions


    Wassim Chegham est un fervent défenseur des technologies Web front et suit de près les versions ECMAScript. Aujourd'hui, il nous propose un article sur les fonctions JavaScript et leurs aspects parfois complexes.

    Cet article parle de la boucle d'événements, du callback, des fonctions anonymes, etc.

    JavaScript pour les Jedis, épisode I : au cœur des fonctions

    N'hésitez pas à lui faire part de vos remarques et commentaires.


  2. #2
    Membre habitué

    Homme Profil pro
    Consultant en technologies
    Inscrit en
    Décembre 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Consultant en technologies
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 32
    Points : 191
    Points
    191
    Par défaut
    Merci Xavier pour la pub

  3. #3
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Merci à toi pour l'article Wassim

    Quand vous aurez tout lu attentivement, vérifiez vos connaissances avec le quiz sur les fonctions sorti récemment.

  4. #4
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 937
    Points
    22 937
    Billets dans le blog
    125
    Par défaut
    VIII-D-4. Invocation via apply() ou call()


    Je trouve que "l'exemple plus intéressant" requiert une meilleure présentation.

    Code JavaScript : 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
    function forevery( list, callback ) {
        var i = 0,
            n = list.length;
     
        for ( i = 0; i < n; i++ ) {
     
            /*
             * Exécute fonction( index ) dans le
             * contexte de l'objet list.
             * argument : i
             */ 
            callback.call( list, i ); 
        };
    }
     
    forevery( [ 'a', 42, false, {} ], function( index ) {
     
        // console, touche F12
     
        console.log( "index = ", index );
        console.log( "this = ", this );
        console.log( "this[ index ] = ", this[ index ] );
        console.log( "this[ index + 1 ] = ", this[ index + 1 ] );
        console.log( "this[ index - 1 ] = ", this[ index - 1 ] );
     
        /*
         *  index =  0
         *  this =  ["a", 42, false, Object]
         *  this[ index ] =  a
         *  this[ index + 1 ] =  42
         *  this[ index - 1 ] =  undefined
         *  
         *  index =  1
         *  this =  ["a", 42, false, Object]
         *  this[ index ] =  42
         *  this[ index + 1 ] =  false
         *  this[ index - 1 ] =  a
         *  
         *  etc.
         */
    });

  5. #5
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut
    Point VII. :
    la portée d'une variable existe depuis sa déclaration*, et ce jusqu'à la fin de la fonction dans laquelle elle a été déclarée, peu importe l'imbrication des blocs (variables declaration hoisting) ;
    Peut-être préciser/insister * avec le mot clé var.

    Beau boulot en tout cas. Par contre, je pense que ça permet de devenir un padawan pour le moment. Jedi quand assimilé les closures, tu auras

  6. #6
    Membre averti
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Points : 362
    Points
    362
    Par défaut
    Il me semble que c'est inexact. Une variable est utilisable dans sa portée de déclaration comme une fonction. C'est à dire même avant l'apparition de 'var' dans le source (variable declaration hoisting).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function foo () {
    	a = 1; // ne crée pas de variable globale
    	       // parce que 'a' est déclaré dans la portée (la fonction)
    	var a; // déclaration de 'a'
    }
    foo();
    // ici la variable 'a' n'existe pas

  7. #7
    Membre habitué

    Homme Profil pro
    Consultant en technologies
    Inscrit en
    Décembre 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Consultant en technologies
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 32
    Points : 191
    Points
    191
    Par défaut
    Merci messieurs pour vos remarques. Je vais regarder cela à tête reposée ce soir.

  8. #8
    Membre habitué

    Homme Profil pro
    Consultant en technologies
    Inscrit en
    Décembre 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Consultant en technologies
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 32
    Points : 191
    Points
    191
    Par défaut
    Citation Envoyé par lysandro Voir le message
    Il me semble que c'est inexact. Une variable est utilisable dans sa portée de déclaration comme une fonction. C'est à dire même avant l'apparition de 'var' dans le source (variable declaration hoisting).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function foo () {
    	a = 1; // ne crée pas de variable globale
    	       // parce que 'a' est déclaré dans la portée (la fonction)
    	var a; // déclaration de 'a'
    }
    foo();
    // ici la variable 'a' n'existe pas
    Cet exemple reste valide mais personnellement je ne recommande pas cette façon de faire.
    Si je dois manipuler une variable locale (à une fonction) je la déclare en haut de la fonction. De toute façon c'est ce que fait l'interrupteur JavaScript.

  9. #9
    Membre averti
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Points : 362
    Points
    362
    Par défaut
    Bien sur, il ne s'agit pas du tout de recommander cette écriture. Mais d'éviter les incompréhensions que vous cherchez justement à lever et par là ne pas faire de différences entre variables et fonctions dans votre article en ce qui concerne la portée et la déclaration puisqu'il n'y en a pas

  10. #10
    Membre habitué

    Homme Profil pro
    Consultant en technologies
    Inscrit en
    Décembre 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Consultant en technologies
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 32
    Points : 191
    Points
    191
    Par défaut
    Nous sommes d'accord alors. Je vais essayer de reformuler cette nuance.

  11. #11
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut
    Citation Envoyé par lysandro Voir le message
    Il me semble que c'est inexact. Une variable est utilisable dans sa portée de déclaration comme une fonction. C'est à dire même avant l'apparition de 'var' dans le source (variable declaration hoisting).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function foo () {
    	a = 1; // ne crée pas de variable globale
    	       // parce que 'a' est déclaré dans la portée (la fonction)
    	var a; // déclaration de 'a'
    }
    foo();
    // ici la variable 'a' n'existe pas
    Tu as quand même utilisé var . C'était mon propos. Elle doit être déclarée avec var pour ne pas être globale.

  12. #12
    Membre averti
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Points : 362
    Points
    362
    Par défaut
    Yep. Ce que à quoi je répondais c'est, dans l'article (où il utilise 'var')
    ... la portée d'une variable existe depuis sa déclaration ...
    et des bricoles après

  13. #13
    Membre habitué

    Homme Profil pro
    Consultant en technologies
    Inscrit en
    Décembre 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Consultant en technologies
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 32
    Points : 191
    Points
    191
    Par défaut
    Citation Envoyé par lysandro Voir le message
    Yep. Ce que à quoi je répondais c'est, dans l'article (où il utilise 'var')
    et des bricoles après
    J'ai changé cette phrase par celle-ci :

    la portée d’une variable (incluant les expressions de fonction) existe depuis sa définition, et ce jusqu’à la fin de la fonction dans laquelle elle a été déclarée, peu importe l’imbrication des blocs.
    Vous êtes d'accord ?

  14. #14
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Non tu n'y es pas. Il n'y a pas de différence entre la portée d'une variable et la portée créée par la fonction dans laquelle cette variable est déclarée. La portée d'une variable locale est la portée locale, et ce peu importe à quel endroit la variable est déclarée.

    On avait déjà abordé la question dans le topic de pré-publication, voilà pour rappel nos échanges:

    - Portée et contexte(s) d’une fonctionla portée d’une variable existe depuis sa déclaration et ce jusqu’à la fin de la fonction dans laquelle elle a été déclarée (peu importe l’imbrication des blocs) ;
    la portée d’une fonction (non*anonyme) est globale à toute la fonction dans laquelle elle a été déclarée (on appelle cela hoisting, ou hissage en français).


    SPV: En fait, les règles de portée sont les mêmes pour tous types de variable, y compris les fonctions. Le hoisting est également présent pour toutes les autres variables, donc la portée de la variable "c" est incorrecte. De même, le hoisting fonctionne pour les fonctions anonymes (à conditions d'être référencé par une variable bien entendu)
    voir : https://developer.mozilla.org/en-US/...r#var_hoisting
    WCH :
    1) hoisting : [CITATION]«En fait, les règles de portée sont les mêmes pour tous types de variable, y compris les fonctions » [/CITATION]
    Attention, ceci est vrai si la fonction est une expression de fonction, càd, qui a été déclarée avec le mot clé « var » (on parle alors du var hoisting, cf. lien var hoisting).
    Une fonction déclarée avec le mot clé « function fn(){} » peut être invoquée avant sa déclaration ; on parle alors de hoisting de fonction (https://developer.mozilla.org/en-US/...ation_hoisting)
    2) portée : l’exemple de la variable « c » est là pour démontrer qu’une variable est dispo dans la chaine de la portée, qu’à partir du moment de sa déclaration (avec ou sans le var). Voici un exemple de code qui permet d’illustrer mes propos :

    SPV : il faut bien s’entendre sur les termes utilisés. Ici tu parles de portée et non d’affectation. Les règles de portée sont les mêmes pour toutes les variables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function foo() { 
       if (false) {
         var x = 1;
      }
      return;
      var y = 1;
    }
    est interprété comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function foo() {  
      var x, y;
      if (false) {
        x = 1;
      }
      return;
      y = 1;
    }
    La difference pour les fonctions non déclarées avec var est que c’est l’ensemble du corps de la fonction qui est déplacé en haut de fonction. Mais toutes les variables ont la même portée au sein d’une fonction. C’est d’ailleurs pour ça qu’on appelle ça une « portée » (scope en anglais). La preuve avec ta fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function fonction1(){
     
      console.log(a+b+c); // NaN
      console.log(a+b+d); // ReferenceError: d is not defined
     
      var a = 1; 
      function fonction2(){ /**/ }
      var b = 2;
      if (a === 1) {
        var c = 3;
      }
    }
    fonction1();
    WCH: Cette deuxième règle nous montre que, contrairement aux variables, les fonctions peuvent
    être référencées avant leurs déclarations !
    SPV: les variables aussi
    WCH : référencer (appeler) une variable avant sa déclaration retournera « undefined » !
    SPV : mais pas de ReferenceError. Donc elle est à portée, mais sa valeur ne lui a pas encore été affectée.
    Je te laisse revoir ces quelques bouts de phrase pour mettre fin à tout malentendu

  15. #15
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut

  16. #16
    Membre éprouvé

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 223
    Points : 1 183
    Points
    1 183
    Par défaut
    Dans le VIII-E, cas #2, le commentaire devrait être "//=> this === foo" non ?

    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
    20
     
    var Foo = function() {
     this.counter = 0;
     this.inc = function() {
     this.counter += 1;
     console.log(this);
     };
    };
     
    var foo = new Foo();
    var element = document.querySelector('#foo');
     
    // cas #1
    element.addEventListener('click', foo.inc); //=> this === element
     
    // cas #2
    element.addEventListener('click', function(){ foo.inc(); }); //=> this === element
     
    // cas #3
    element.addEventListener('click', foo.inc.bind(foo)); //=> this === foo

  17. #17
    Membre du Club
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 44
    Points
    44
    Par défaut +1
    Citation Envoyé par idiallo Voir le message
    Dans le VIII-E, cas #2, le commentaire devrait être "//=> this === foo" non ?
    Il me semble aussi.

  18. #18
    Membre habitué

    Homme Profil pro
    Consultant en technologies
    Inscrit en
    Décembre 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Consultant en technologies
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 32
    Points : 191
    Points
    191
    Par défaut
    Oops! Mauvais copié collé. Bien vu oeil de lynx

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