Question

Je suis en train de faire une fonction qui maintient l'état, mais est appelée avec foo ().
Est-il possible?

Était-ce utile?

La solution

Je crois que c'est ce que vous voulez:

var foo = (function () {
    var state = 0;

    return function () {
        return state++;
    };
})();

Ou, l'exemple de Wikipedia :

var makeAccumulator = function (n) {
    return function (x) {
        n += x;
        return n;
    };
};

var acc = makeAccumulator(2);

alert(acc(2)); // 4
alert(acc(3)); // 7

JavaScript est l'une de ces langues qui a, à mon humble avis, un excellent soutien pour les fonctions comme des citoyens de première classe.

Autres conseils

Puisque les fonctions Javascript sont des objets de première classe, c'est la façon de le faire:

var state = 0;
var myFunctor = function() { alert('I functored: ' + state++);};

La variable state sera disponible à la fonction myFunctor dans sa fermeture locale. (Global dans cet exemple). Les autres réponses à cette question ont des exemples les plus sophistiqués.

Il n'y a pas équivalent à seulement « opérateur d'exécution () » sur un objet existant, cependant.

Vous pouvez traiter des fonctions comme des objets et leur donner des « variables membres ». Ici nous utilisons une fonction interne fact, mais au lieu de simplement déclarer comme une variable locale (var loop = ...), nous mettons sa définition en dehors de la fonction, en utilisant la syntaxe d'objet (fact.loop = ...). Cela nous permet essentiellement « exporter » la fonction loop interne de fact afin qu'il puisse être réutilisé par la fonction doubleFact.

var fact = function(n) {
  return fact.loop(n, 1);
};

fact.loop = function(n, acc) {
  if (n < 1) {
    return acc;
  } else {
    return fact.loop(n-1, acc * n);
  }
};

var doubleFact = function(x) {
  return fact.loop(x * 2, 1);
};

console.log(fact(5)); // 120
console.log(doubleFact(5)); // 3628800

pourrait être utilisé la même idée de maintenir l'état.

var countCalled = function() {
  console.log("I've been called " + (++countCalled.callCount) + " times.");
};

countCalled.callCount = 0;

countCalled(); // I've been called 1 times.
countCalled(); // I've been called 2 times.
countCalled(); // I've been called 3 times.

Si vous voulez être en mesure d'instancier plusieurs petits, chacun avec leur propre état, essayez ceci:

var CallCounter = function(name) {
  var f = function() {
    console.log(name + " has been called " + (++f.callCount) + " times.");
  };
  f.callCount = 0;
  return f;
};

var foo = CallCounter("foo");
var bar = CallCounter("bar");

foo();
foo();
bar();
foo();
bar();
bar();
bar();

console.log(foo.callCount);
console.log(bar.callCount);

Sorties:

foo has been called 1 times.
foo has been called 2 times.
bar has been called 1 times.
foo has been called 3 times.
bar has been called 2 times.
bar has been called 3 times.
bar has been called 4 times.
3
4

Vous pouvez utiliser la fonction de retour de fermeture avec des propriétés d'objet de la fonction ci-joint. Les paramètres de cette foncteur (fermeture) peuvent être modifiés après l'initialisation, qui peut être utile pour la construction de certains calcul qui peut être exécuté / configuré plus tard. Jetez un oeil à exemple ci-dessous. Cette réponse est similaire à limp_chimp.

function functor() {

  var run = function runX() {

    return runX.functorParam;

    // or: 

    // return run.functorParam;
  };

  run.functorParam = 'functor param'; // default value

  return run;
}

var f1 = functor();

// call f1
f1(); // 'functor param'


// lets change functor parameters:
f1.functorParam = 'Hello';


// call f1
f1(); // 'Hello'

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top