Maison > interface Web > js tutoriel > Divers pièges et méthodes de remplissage des pièges dans le code JavaScript compétences d'écriture_javascript

Divers pièges et méthodes de remplissage des pièges dans le code JavaScript compétences d'écriture_javascript

WBOY
Libérer: 2016-05-16 16:45:50
original
1369 Les gens l'ont consulté

Le mot « fosse » signifie ici « piège ». En raison de la nature du « langage faible » de JavaScript, il est extrêmement lâche et flexible lors de son utilisation, mais il est également extrêmement facile de « tomber dans ces pièges ». caché , vous devez donc garder les yeux ouverts pour pouvoir voyager en douceur sur la voie de l'apprentissage et de l'application de JS

1. Variables globales

JavaScript gère la portée via des fonctions. Les variables déclarées à l'intérieur d'une fonction ne sont disponibles qu'à l'intérieur de la fonction et ne sont pas disponibles en dehors de la fonction. En revanche, les variables globales sont déclarées en dehors de toute fonction ou simplement utilisées sans être déclarées.

"Utilisation simple sans déclaration" fait référence à la déclaration de variables sans utiliser le mot-clé var. Nous le savons déjà très bien. Le moyen d’éviter de générer implicitement des variables globales est de déclarer autant que possible les variables en utilisant le mot-clé var.

Mais pensez-vous qu'utiliser var est acceptable ? Jetons un coup d'oeil à cette fosse :

Copiez le code Le code est le suivant :

function foo() {
var a = b = 0;
// corps...
}

Peut-être vous attendiez-vous à deux variables locales, mais b est une vraie variable globale. pourquoi ? Parce que les opérations d'affectation se font de droite à gauche, cela équivaut donc à :

Copier le code Le code est le suivant :

function foo() {
var a = (b = 0);
// corps...
}

Donc b est une variable globale.

Remplissez le trou : déclarations de variables, il vaut mieux les faire une par une, ne pas faire en gros~_~;

2. Déclaration de variable

Regardons d'abord les pièges :

Copier le code Le code est le suivant :

myName = "global";

function foo() {
alert(myName);
var myName = "local ";
alert(myName);
}

foo();

À première vue, on s'attend à ce que les résultats des deux alertes soient "globaux" et "locals ", mais le réel Les résultats sont "indéfinis" et "locals". pourquoi ? Étant donné que les variables sont dans la même portée (même fonction), les déclarations sont placées en haut de la portée et analysées en premier.

Le comportement d'exécution de l'extrait de code ci-dessus pourrait donc être le suivant :

Copiez le code Le code est le suivant :

function foo() {
var monNom;
alert(monNom); // "non défini"
monNom = "local";
alert(monNom); // "local"
}

Utilisez une autre fosse pour tester si vous comprenez vraiment la pré-analyse :
Copier le code Le code est le suivant :

if (!("a" dans la fenêtre)) {
var a = 1;
}

alerte (a);

La déclaration d'une variable est avancée en haut du code et n'a pas encore reçu de valeur. Ensuite, entrez l'instruction if. La condition de jugement "a" dans la fenêtre a été établie (a a été déclarée comme variable globale), donc le résultat de l'évaluation de l'instruction de jugement est faux, et l'instruction if est sautée directement, donc l'instruction if. la valeur de a n’est pas définie.
Copier le code Le code est le suivant :

var a; // "indéfini"
console .log("a" in window); // true

if (!("a" in window)) {
var a = 1; // Ne pas exécuter
>

alert(a); // "undefined"

Remplissez la fosse : déclaration de variable, il est préférable de la placer manuellement en haut de la portée Pour les variables qui ne peuvent pas l'être. attribué immédiatement, vous pouvez d'abord déclarer puis attribuer.

3. Déclaration de fonction

Les déclarations de fonctions sont également avancées en haut de la portée, analysées et évaluées avant toute expression et instruction

Copier le codeLe le code est le suivant :

alert(typeof foo); // "function"

function foo() {
// body...
}

Vous pouvez comparer :
Copiez le code Le code est le suivant :

alert(typeof foo); // "indéfini"

var foo = function () {
// corps...
};

Après avoir compris cette vérité, tomberez-vous encore dans les pièges suivants ?

Copier le code Le code est le suivant :

function test() {
alerte ("1");
}

test();

function test() {
alert("2");
}

test( );

Exécutez l'extrait de code ci-dessus et les deux fenêtres contextuelles que vous voyez affichent "2". Pourquoi ne sont-elles pas respectivement "1" et "2" ? Très simplement, la déclaration de test est analysée avant test(), et comme cette dernière écrase la première, le résultat des deux exécutions est "2".

Remplissez le trou : dans la plupart des cas, j'utilise des expressions de fonction au lieu de déclarations de fonction, en particulier dans certains blocs d'instructions.

4. Expressions de fonction

Regardons d'abord les expressions de fonction nommées Bien sûr, elles doivent avoir un nom, par exemple :

Copier le code Le code est le suivant :
var bar = function foo() {
// body...
};
Il est à noter que le nom de la fonction n'est visible qu'à l'intérieur de sa fonction. Tels que les écueils suivants :

Copier le code Le code est le suivant :
var bar = function foo() {
foo(); // Fonctionnement normal
};

foo(); // Erreur : ReferenceError
Remplissez le trou : utilisez le moins possible les expressions de fonctions nommées (sauf à des fins de récursivité et de débogage) et n'utilisez jamais de noms de fonctions en externe.

5. Auto-exécution des fonctions

Pour les expressions de fonction, vous pouvez vous auto-exécuter en ajoutant () après, et vous pouvez passer des paramètres entre parenthèses, mais les déclarations de fonction ne le peuvent pas. . Piège :

Copier le code Le code est le suivant :
// (1) Ceci est juste un symbole d'opération de regroupement, pas un appel de fonction !
// Donc la fonction ici n'a pas été exécutée, c'est toujours une instruction
function foo(x) {
alert(x);
}(1);
Les extraits de code suivants sont respectivement La fenêtre contextuelle affiche "1" pendant l'exécution, car tout ce qui précède (1) est une expression de fonction, donc () ici n'est pas un opérateur de regroupement, mais un opérateur indiquant l'exécution de l'appel.

Copier le code Le code est le suivant :
// Expression de fonction anonyme standard
var bar = function foo(x) {
alert(x);
}(1);

// Le précédent () convertit la déclaration de fonction en une expression
(function foo(x) {
alert(x);
})(1);

// Le tout () est l'expression
(function foo(x) {
alert(x) ;
}(1));

// nouvelle expression
nouvelle fonction foo(x) {
alert(x);
}(1);

// &&, ||, !, , -, ~ opérateurs (et virgules), lever l'ambiguïté des expressions de fonction et des déclarations de fonction
// donc une fois que l'analyseur sait que l'un d'eux est déjà une expression, et tout le reste est par défaut aux expressions
true && function foo(x) {
alert(x);
}(1);
Remplissez la fosse : cette fosse La clé est de comprendre l'essence de diverses expressions de fonctions.

6. Fermetures en boucles
Ce qui suit démontre un piège courant :

Copier le code Le code est le suivant :




   
Document


   

lorsque vous cliquez sur les liens ci-dessous, affichez le numéro de sa séquence


    < ;ul>
       
  • link #0

  •        
  • link #1

  •        
  • lien #2

  •        
  • lien n°3

  •        
  • lien n°4

  •    


    复制代码 代码如下 :

    var links = document.getElementsByTagName("ul")[ 0].getElementsByTagName("a");

    for (var i = 0, l = links.length; i < l; i ) {
        links[i].onclick = function (e ) {
            e.preventDefault();
            alert("Vous cliquez sur le lien #" i);
        }       
    }

    我们预期当点击第 i 个链接时,得到此序列索引 i 的值,可实际无论点击哪个链接,得到的都Et je 在循环后的最终结果:”5”。

    解释一下原因:当 alerte 被调用时,pour 循环内的匿名函数表达式,保持了对外部变量 i的引用(闭包),此时循环已结束,i 的值被修改为 « 5 » 。

    填坑 : 为了得到想要的结果 , 需要在每次循环中创建变量 i 的拷贝。以下演示正确的做法 :

    复制代码 代码如下 :


       
        Document


       

    lorsque vous cliquez sur les liens ci-dessous, affichez le nombre de sa séquence


       


    复制代码 代码如下 :

    var links = document.getElementsByTagName(“ul”)[ 0].getElementsByTagName("a");
    for (var i = 0, l = links.length; i < l; i ) {
        links[i].onclick = (function (index) {

    Comme vous pouvez le voir, la forme de (function () { ... })() est l'auto-exécution de la fonction mentionnée ci-dessus, i est transmise à l'index en tant que paramètre. Lorsque l'alerte est à nouveau exécutée, elle est transmise à l'index. aura une référence à l'index, cette valeur ne sera pas modifiée cycliquement pour le moment. Bien sûr, après avoir compris le principe, vous pouvez aussi écrire comme ceci :

    Copier le code Le code est le suivant :

    pour (var i = 0, l = links.length ; i < l; i ) {
    (fonction (index) {
    links[i].onclick = function (e) {
    e.preventDefault();
    alert( "Vous cliquez sur le lien #" index);
    }
    })(i);
    }

    Ça marche aussi.

    Étiquettes associées:
    source:php.cn
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal