web-dev-qa-db-fra.com

Fonction imbriquée JavaScript

J'ai un morceau de code pour javascript que je ne comprends tout simplement pas:

function dmy(d) {
    function pad2(n) {
        return (n < 10) ? '0' + n : n;
    }

    return pad2(d.getUTCDate()) + '/' +
       pad2(d.getUTCMonth() + 1) + '/' +
       d.getUTCFullYear();
}

function outerFunc(base) {
    var punc = "!";

    //inner function
    function returnString(ext) {
       return base + ext + punc;
    }

    return returnString;
}

Comment une fonction peut-elle être définie dans une autre fonction? Pouvons-nous appeler pad2 () de l'extérieur de ma fonction ()?

S'il vous plaît mettre un peu de lumière dessus. Merci

87
Thomas

Les fonctions sont un autre type de variable en JavaScript (avec quelques nuances bien sûr). La création d'une fonction dans une autre fonction modifie la portée de la fonction de la même manière que la portée d'une variable. Ceci est particulièrement important pour une utilisation avec des fermetures afin de réduire la pollution totale de l'espace de noms mondial.

Les fonctions définies dans une autre fonction ne seront accessibles en dehors de la fonction que si elles ont été attachées à un objet accessible en dehors de la fonction:

function foo(doBar)
{
  function bar()
  {
    console.log( 'bar' );
  }

  function baz()
  {
    console.log( 'baz' );
  }

  window.baz = baz;
  if ( doBar ) bar();
}

Dans cet exemple, la fonction baz sera disponible après la fonction foo, car elle est remplacée par window.baz. La fonction de barre ne sera disponible dans aucun contexte autre que les étendues contenues dans la fonction foo.

comme exemple différent:

function Fizz(qux)
{
  this.buzz = function(){
    console.log( qux );
  };
}

La fonction Fizz est conçue comme un constructeur, de sorte que, lors de son exécution, elle attribue une fonction buzz au nouvel objet créé.

134
zzzzBov

Cela s'appelle fermeture .

Fondamentalement, la fonction définie dans une autre fonction n'est accessible que dans cette fonction. Mais peut être passé comme résultat et ensuite ce résultat peut être appelé.

C'est une fonctionnalité très puissante. Vous pouvez voir plus d'explications ici:

javascript_closures_for_dummies.html miroir sur Archive.org

32
Tadeck
function x() {}

est équivalent (ou très similaire) à

var x = function() {}

sauf si je me trompe.

Donc, il n'y a rien de drôle.

13
Andreas

L'instanciation de fonction est autorisée à l'intérieur et à l'extérieur des fonctions. À l'intérieur de ces fonctions, tout comme les variables, les fonctions imbriquées sont locales et ne peuvent donc pas être obtenues à partir de la portée extérieure.

function foo() {
    function bar() {
        return 1;
    }
    return bar();
}

foo manipule bar en lui-même. bar ne peut être touché depuis la portée externe que si elle est définie dans la portée externe.

Donc cela ne fonctionnera pas:

function foo() {
    function bar() {
        return 1;
    }
}

bar(); // throws error: bar is not defined
9
0x499602D2

Lorsque vous déclarez une fonction dans une fonction, les fonctions internes ne sont disponibles que dans l'étendue dans laquelle elles ont été déclarées ou, dans votre cas, le pad2 ne peut être appelé que dans l'étendue dmy.

Toutes les variables existant dans dmy sont visibles dans pad2, mais cela ne se produit pas dans l'autre sens: D

4
pedrochaves

Il est parfaitement normal en Javascript (et dans beaucoup de langues) d'avoir des fonctions à l'intérieur de fonctions.

Prenez le temps d'apprendre la langue, ne l'utilisez pas parce que c'est similaire à ce que vous connaissez déjà. Je suggérerais de regarder la série de présentations de YUI de Douglas Crockford sur Javascript, avec un accent particulier sur Acte III: Fonctionner l'ultime (lien vers téléchargement de vidéo, diapositives et transcription)

3
Joaquim Rendeiro