web-dev-qa-db-fra.com

Portée variable de la boucle JavaScript

Juste une petite question sur la portée des variables JavaScript.

Pourquoi la fonction alert() affiche-t-elle la valeur de i au lieu de renvoyer undefined?

$(document).ready(function () {
    for(var i = 0; i < 10; i += 1){
    }

     alert("What is 'i'? " + i);
});

Je suis assez nouveau pour JS et, dans presque toutes les autres langues que j'ai consultées, une déclaration dans le champ de la boucle for contiendrait la valeur de ladite boucle, mais pas dans ce cas, pourquoi?

c'est à dire. What is 'i'? 10' est imprimé.

56
BlackBox

Voir le MDN pour le " paramètres d'initialisation " d'une for- boucle :

Une expression (y compris les expressions d'affectation) ou une déclaration de variable. Généralement utilisé pour initialiser une variable de compteur. Cette expression peut éventuellement déclarer de nouvelles variables avec le mot clé var. Ces variables ne sont pas locales à la boucle, c’est-à-dire qu’elles ont la même étendue que celle de la boucle for. Le résultat de cette expression est ignoré.

65
insertusernamehere

JavaScript n'avait pas de portée de bloc jusqu'à ce que const et let aient été introduits, juste var qui est une fonction étendue. Comme l'initialisation de i fait partie d'une fonction, cette variable est accessible n'importe où ailleurs dans la même fonction.

De MDN :

Important: JavaScript n'a pas de portée de blocage. Les variables introduites avec un bloc sont étendues à la fonction ou au script qui les contient et les effets de leur définition persistent au-delà du bloc lui-même. En d'autres termes, les instructions de bloc n'introduisent pas d'étendue. Bien que les blocs "autonomes" constituent une syntaxe valide, vous ne souhaitez pas utiliser de blocs autonomes en JavaScript, car ils ne font pas ce que vous pensez qu'ils font, si vous pensez qu'ils agissent de la même manière que ces blocs en C ou en Java.

54
user2718994

Les gens de javascript essaient de résoudre ce problème!

EcmaScript6 (EcmaScript 2015) est la dernière version de javascript adoptée l'été dernier et les navigateurs commencent tout juste à prendre en charge ses fonctionnalités.

L'une de ces fonctionnalités est constituée par les variables locales à portée de bloc avec l'expression "let". À l'heure actuelle (avril 2016), la plupart des versions actuelles des principaux navigateurs le prennent en charge, à l'exception de Safari. Peu de navigateurs mobiles le supportent.

Vous pouvez en savoir plus à ce sujet ici (en particulier, voir la section "Variables let-scoped dans des boucles for"): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Déclarations/let

Vous pouvez vérifier la prise en charge du navigateur actuel ici (recherchez la ligne Bindings -> let): https://kangax.github.io/compat-table/es6/

16
Matt Coarr

Contrairement à d'autres langages (par exemple: Java, C++, C), JavaScript ne prend pas en charge l'étendue des blocs. Une fois que vous déclarez une variable dans une boucle ou dans une fonction, sa portée est dans le corps de la fonction si vous le faites.

for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

ici, votre i devient une variable globale et j devient local à la fonction ou au script dans lequel se trouve la boucle.

10
Hitesh Kumar
for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

il n'est pas correct de dire que ce qui précède crée une variable globale i. Je crois que vous devriez toujours utiliser var pour déclarer des variables (à moins que vous ne vouliez intentionnellement une "propriété" plutôt qu'une "variable" - ce qui est plutôt improbable dans 99,99% des scénarios de codage JS ...)

Omettre var lorsque l’attribution d’une valeur initiale à i ne crée pas de variable locale ou même globale, il crée une propriété i pour l’objet global (qui peut sembler/se comporte principalement comme une variable globale - mais ils ont quelques différences subtiles).

mieux serait:

var i;
for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

la boucle utilise maintenant une variable globale i (ou une variable locale de fonction i, si ce code apparaît dans une fonction)

en savoir plus à ce sujet sur fonction du mot-clé var et variables et propriétés en Javascript

- remarque, ce qui est un peu déroutant, c'est que vous pouvez déclarer une variable, par exemple dans une seconde boucle

for(var i=0; i<9; i++){
    document.write('i = ' + i + '<br>');
}


for(var i=0; i<9; i++){
    document.write('i = ' + i + '<br>');
}

cela semble être valide (aucune erreur lorsque je teste). Il semble que vous POUVEz re-déclarer des variables en JavaScript - mais ce n'est probablement pas une bonne idée, sauf cas spécial - voir cette question connexe indiquant comment [Google Analytics utilise la redéclaration "sûre" d'une variable] ( Redéclarer une variable javascript )

il y a des discussions sur la re-déclaration des variables dans JS (et aussi des variables de boucle comme i) dans ce contexte SO question: déclarer des variables à l'intérieur ou à l'extérieur de la boucle

Il existe un événement a modèle JavaScript pour la déclaration unique de variables

9
Matt Smith