44 votes

Quels modèles de conception tirent parti du comportement de levage de JavaScript?

Ben Cerise à l'excellent article explique de levage en JavaScript de manière adéquate. Mon problème, cependant, est que je ne peux pas concevoir un cas d'utilisation de ce tristement célèbre auteur de la confusion. Veuillez expliquer si il y a un modèle de conception qui prend avantage de cette fonctionnalité du langage.

Deuxièmement, est à la portée de levage unique pour le JavaScript?

Mise à JOUR --- je suis en ajoutant une prime pour une réponse qui satisfait ma curiosité: le design pattern(s) en fait de prendre avantage de JavaScript de levage comportement? Je comprends pourquoi JavaScript prend en charge de levage, mais je veux savoir comment je peux profiter de cette fonctionnalité.

19voto

Dagg Nabbit Points 23918

Variable de levage

L'un des plus simple, les utilisations de levage est variable de levage. Si nous n'avions pas de variable de levage, ce serait jeter un ReferenceError:

var bar = foo; 
var foo;

Cela ne semble pas utile dans l'immédiat, mais il nous permet de faire les choses comme ceci:

var myCoolJS = myCoolJS || {};

Ceci signifie fondamentalement à quoi il ressemble: myCoolJS est myCoolJS si elle existe, ou d'un nouvel objet si elle ne le fait pas. Le deuxième myCoolJS ne pas jeter un ReferenceError si myCoolJS n'existe pas déjà, parce que cette déclaration de variable est hissé.

Cela nous évite de faire un peu maladroite typeof myCoolJS != 'undefined' vérifier.

Fonction de levage

Fonction de levage peut être particulièrement utile lors de la combinaison de plusieurs scripts en un seul. Par exemple, j'ai créé un léger moment de la construction, de la mise en œuvre de CommonJS modules. Cela fournit le même module, require, et exports fonctionnalités que l'on trouve dans node.js. J'ai construit l'outil pour permettre aux modules requis pour être composé de plusieurs fichiers. Par exemple, require('/foo') pourrait entraîner un module composé de deux fichiers, foo.js (le "corps" du fichier") et foo.h.js (le "fichier d'en-tête").

Cela permet au corps "fichier" de n'avoir aucune connaissance de la libre variables fournies par le CommonJS modules de l'environnement; tout cela est géré dans l'en-tête. Cela rend le code réutilisable et facile à tester sans bâtiment. Cependant, depuis les en-têtes sont précédées du corps, nous tirons parti de la fonction de levage dans le corps du fichier à autoriser des exportations dans les en-têtes. Par exemple:

// dom.h.js

var util = require('util').util;

exports.css = css; // we can do this because "css" is hoisted from below

// ... other exports ...

...

// dom.js

function css(){}; // this would normally just be an object.

css.hasClass = function(element) { ... };
css.addClass = function(element) { ... };

// ...other code...

15voto

Jordan Miner Points 1476

Voici une utilisation pour de levage:

(function() {
    var factorial = function(n) {
        if(n == 0)
            return 1;
        return n * factorial(n - 1);
    };
})();

Sans de levage, qui ne se compile pas, car factorial n'existe pas encore à l'intérieur de la fonction littérale. Vous devez déclarer la variable séparément ou d'utiliser une fonction nommée.

JavaScript permet également un code comme suit:

var test = function(b) {
    if(b) {
        var value = 2;
    } else {
        var value = 5;
    }
    console.log(value);
};

Avec bloc de portée, vous devez ajouter une autre ligne à déclarer value avant l' if.

Pour être juste, ce code fonctionne en raison de la portée de la fonction, pas de levage. Et le JavaScript n'ont eu de portée de la fonction sans de levage. Ruby gère mieux: Ruby a la portée de la méthode pour les variables, mais les variables n'existent pas jusqu'à ce que vous les définissez:

def test(b)
    # unlike JavaScript, value is not accessible here
    if b
        value = 2
    else
        value = 5
    end
    puts value
end

11voto

alex Points 186293

JavaScript n'a pas de bloc de portée (oublions let pour l'instant) et donc toute déclaration de variable se déclarant pour l'ensemble de la fonction, de JavaScript qui n' ont portée.

Si vous pensez comme cela, JavaScript levage peut-être plus de sens.

Si vous vous en souvenez, de levage, il ne devrait pas être une source de bugs et de confusion. C'est tout simplement l'une de ces bizarreries que vous devez comprendre et à mémoriser.

Je ne suis pas sûr si de levage est limitée à JavaScript. Je n'ai jamais entendu parler de ça ailleurs, mais cela ne veut pas nécessairement dire qu'elle n'existe pas dans d'autres langues.

9voto

Šime Vidas Points 59994

Les deux premiers exemples dans cet article sont tout simplement mal écrit. Code incorrect conduit évidemment à des bugs et de la confusion. Permettez-moi de vous donner la refonte des versions de ces exemples. Vous verrez qu'il n'y est pas de confusion ici...

Exemple 1 - code d'Origine

var foo = 1;
function bar() {
    if (!foo) {
        var foo = 10;
    }
    alert(foo);
}
bar();

Exemple 1 - Refonte du code (retiré de la confusion)

var foo = 1;

function bar() {
    var foo;

    if ( !foo ) {
        foo = 10;
    }

    alert( foo );
}

bar();

L'alerte affiche "10", et il est clair pourquoi. Pas de confusion ici.

Exemple 2 - le code d'Origine

var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);

Exemple 2 - Refonte du code (retiré de la confusion)

var a = 1;

function b() {
    var a = function () {}; 
    a = 10;
    return; 
}

b();

alert( a );

L'alerte affiche "1". Évidemment. Pas de confusion ici, trop.

6voto

Fireblaze Points 134

"levage" ne fait pas partie du Standard ECMAScript, mais il ne dit que la variable à l'intérieur d'une fonction sont déclarées au début de la fonction, peu importe où dans le rôle qu'elle est dans le code.

Exemple

(function() {
  alert(myvar); // undefined
  var myvar = 'local value';
})();

En interne Javascript serait déclarer myvar avant l'alerte, montrer l'alerte, alors il faudrait attribuer myvar à local "valeur".

Donc, Javascript serait interpet ce code comme:

(function() {
  var myvar;
  alert(myvar); // undefined
  myvar = 'local value';
})();

C'est pourquoi "de Java, les Bonnes pièces" a une directive qui disent que vous devez déclarer la variable en haut de votre fonction.

Source: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/

"Veuillez expliquer si il y a un modèle de conception qui prend avantage de cette fonctionnalité du langage." "levage" n'est pas une fonction mais plutôt une conséquence de la façon dont l'interpréteur Javascript de la structure du code, étant donné que la langue utilise la fonction de la portée des projets.

"Le design pattern(s) en fait de prendre avantage de JavaScript de levage comportement? " Réponse: Aucune.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X