REMARQUE : Cette question a été posée du point de vue d'ECMAScript version 3 ou 5. Les réponses pourraient devenir obsolètes avec l'introduction de nouvelles fonctionnalités dans la version d'ECMAScript 6.
Quelle est exactement la fonction du var
mot - clé en JavaScript et quelle est la différence entre
var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;
et
someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;
?
Quand utiliseriez-vous l'un ou l'autre et pourquoi / que fait-il?
Réponses:
Si vous êtes dans la portée mondiale, il n'y a pas beaucoup de différence. Lisez la réponse de Kangax pour l'explication
Si vous êtes dans une fonction, alors
var
créera une variable locale, "no var" recherchera la chaîne de portée jusqu'à ce qu'il trouve la variable ou atteigne la portée globale (à quel point il la créera):Si vous ne faites pas de mission, vous devez utiliser
var
:la source
Il y a une différence .
var x = 1
déclare une variablex
dans la portée actuelle (aka contexte d'exécution). Si la déclaration apparaît dans une fonction - une variable locale est déclarée; s'il est de portée globale - une variable globale est déclarée.x = 1
, d'autre part, n'est qu'une cession de propriété. Il essaie d'abord de résoudre lax
chaîne de portée. S'il le trouve n'importe où dans cette chaîne de portée, il effectue une affectation; s'il ne trouve pasx
, alors seulement il crée unex
propriété sur un objet global (qui est un objet de niveau supérieur dans une chaîne de portée).Maintenant, notez qu'il ne déclare pas de variable globale, il crée une propriété globale.
La différence entre les deux est subtile et peut être déroutante à moins que vous ne compreniez que les déclarations de variables créent également des propriétés (uniquement sur un objet variable) et que chaque propriété en Javascript (enfin, ECMAScript) a certains indicateurs qui décrivent leurs propriétés - ReadOnly, DontEnum et DontDelete.
Puisque la déclaration de variable crée une propriété avec l'indicateur DontDelete, la différence entre
var x = 1
etx = 1
(lorsqu'elle est exécutée dans la portée globale) est que la première - déclaration de variable - crée la propriété DontDelete'able, et pas la dernière. Par conséquent, la propriété créée via cette affectation implicite peut ensuite être supprimée de l'objet global, et la première - celle créée via la déclaration de variable - ne peut pas être supprimée.Mais ce n'est qu'une théorie bien sûr, et dans la pratique, il y a encore plus de différences entre les deux , en raison de divers bogues dans les implémentations (comme ceux d'IE).
J'espère que tout cela a du sens:)
[Mise à jour 2010/12/16]
Dans ES5 (ECMAScript 5; 5e édition du langage récemment normalisée), il existe un soi-disant «mode strict» - un mode de langue opt-in, qui modifie légèrement le comportement des affectations non déclarées. En mode strict, l'affectation à un identifiant non déclaré est une ReferenceError . La raison en était de capturer des affectations accidentelles, empêchant la création de propriétés globales indésirables. Certains des navigateurs les plus récents ont déjà commencé à prendre en charge le mode strict. Voir, par exemple, ma table compat .
la source
delete
une variable déclarée var avec un peu deeval
hack. Si je me souviens de l'astuce exacte que je posterai ici.var someObject = {}
etsomeObject.someProperty = 5
? DeviendraitsomeProperty
global, alors que l'objet dont il est la propriété reste local?false
) , vous pouvez en lire plus à propos deObject.defineProperty
etObject.getOwnPropertyDescriptor
Dire que c'est la différence entre « local et global » n'est pas tout à fait exact.
Il serait peut-être préférable de la considérer comme la différence entre « local et le plus proche ». Le plus proche peut certainement être mondial, mais ce ne sera pas toujours le cas.
la source
outer
définievar global = false;
?var global = local;
en auquel cas la portée proche de local serait la portée extérieure "locale" qui est activement définie. Bien que cela devienne étrange si vous changez cette même ligne,var global = global
auquel cas la portée la plus proche lors de la recherche de la valeur deglobal
serait d'un niveau au niveau de la fenêtre globale.Lorsque Javascript est exécuté dans un navigateur, tout votre code est entouré d'une instruction with, comme ceci:
Plus d'infos sur
with
- MDNPuisque
var
déclare une variable dans la portée actuelle , il n'y a aucune différence entre déclarer à l'var
intérieur de la fenêtre et ne pas le déclarer du tout.La différence survient lorsque vous n'êtes pas directement à l'intérieur de la fenêtre, par exemple à l'intérieur d'une fonction ou à l'intérieur d'un bloc.
L'utilisation
var
vous permet de masquer des variables externes portant le même nom. De cette façon, vous pouvez simuler une variable "privée", mais c'est un autre sujet.Une règle d'or est de toujours utiliser
var
, car sinon vous courez le risque d'introduire des bugs subtils.EDIT: Après les critiques que j'ai reçues, je voudrais souligner ce qui suit:
var
déclare une variable dans la portée actuellewindow
var
déclarations implicitesvar
dans la portée globale (fenêtre)var
revient à l'omettre.var
n'est pas la même chose que déclarer une variable sansvar
var
explicitement car c'est une bonne pratiquela source
let
dans ES6.Utilisez toujours le
var
mot - clé pour déclarer des variables. Pourquoi? Une bonne pratique de codage devrait être une raison suffisante en soi, mais l'omettre signifie qu'elle est déclarée dans la portée globale (une variable comme celle-ci est appelée globale "implicite"). Douglas Crockford recommande de ne jamais utiliser de globaux implicites , et selon les directives de codage JavaScript d'Apple :la source
good coding practice
c'est toujours une raison suffisante s'il s'agit d'une meilleure pratique recommandée, ce qui est le cas et de plusieurs auteurs Javascript.Voici un assez bon exemple de la façon dont vous pouvez éviter de déclarer des variables locales avec
var
:(
i
est réinitialisé à chaque itération de la boucle, car il n'est pas déclaré localement dans lafor
boucle mais globalement) entraînant finalement une boucle infiniela source
Je dirais qu'il vaut mieux l'utiliser
var
dans la plupart des situations.Les variables locales sont toujours plus rapides que les variables de portée globale.
Si vous n'utilisez pas
var
pour déclarer une variable, la variable aura une portée globale.Pour plus d'informations, vous pouvez rechercher "chaîne de portée JavaScript" dans Google.
la source
N'utilisez pas
var
!var
était la manière pré-ES6 de déclarer une variable. Nous sommes maintenant dans le futur , et vous devriez coder comme tel.Utiliser
const
etlet
const
doit être utilisé dans 95% des cas. Il fait en sorte que la référence de variable ne puisse pas changer, donc les propriétés de tableau, d'objet et de nœud DOM peuvent changer et devraient probablement l'êtreconst
.let
doit être utilisé pour toute variable devant être réaffectée. Cela inclut une boucle for. Si vous écrivezvarName =
au-delà de l'initialisation, utilisezlet
.Les deux ont une portée au niveau du bloc, comme prévu dans la plupart des autres langues.
la source
une autre différence par exemple
tandis que
la source
var
?var a
est hissé en haut de la portée et défini sur null qui déclare mais n'initialise pas la variable, puis dans l'affectation, vous avez une référence à une variable null non définie qui est évaluée à false et définissez l'affectation sur[]
. Dans ce dernier, vous avez une affectation à la propriétéa
de la propriétéa
. Vous pouvez attribuer à une propriété qui n'existe pas - en la créant lors de l'affectation, mais vous ne pouvez pas lire à partir d'une propriété qui n'existe pas sans avoir étéReferenceError
jeté sur vous.L'utilisation
var
est toujours une bonne idée pour empêcher les variables d'encombrer la portée globale et les variables d'entrer en conflit les unes avec les autres, provoquant un écrasement indésirable.la source
Sans
var
- variable globale.Fortement recommandé d' utiliser TOUJOURS l'
var
instruction, car la variable globale init dans le contexte local - est mauvaise. Mais si vous avez besoin de cette sale astuce, vous devez écrire un commentaire au début de la page:la source
Voici un exemple de code que j'ai écrit pour que vous compreniez ce concept:
la source
@Chris S a donné un bel exemple montrant la différence pratique (et le danger) entre
var
et nonvar
. En voici un autre, je trouve celui-ci particulièrement dangereux car la différence n'est visible que dans un environnement asynchrone et peut donc facilement passer pendant les tests.Comme vous vous en doutez, les extraits de code suivants
["text"]
:Il en va de même pour l'extrait de code suivant (notez ce qui manque
let
avantarray
):L'exécution asynchrone de la manipulation des données produit toujours le même résultat avec un seul exécuteur:
Mais se comporte différemment avec plusieurs:
En utilisant let cependant:
la source
Comme quelqu'un essaie d'apprendre cela, c'est ainsi que je le vois. Les exemples ci-dessus étaient peut-être un peu trop compliqués pour un débutant.
Si vous exécutez ce code:
La sortie se lira comme suit: faux, faux, vrai, vrai
Parce qu'il voit les variables dans la fonction comme distinctes de celles en dehors d'elle, d'où le terme variable locale et c'est parce que nous avons utilisé var dans l'affectation. Si vous supprimez la var dans la fonction, elle se lit maintenant comme suit:
La sortie est fausse, fausse, fausse, fausse
En effet, plutôt que de créer une nouvelle variable dans la portée ou la fonction locale, elle utilise simplement les variables globales et les réaffecte à false.
la source
Je vois que les gens sont confus lorsqu'ils déclarent des variables avec ou sans var et à l'intérieur ou à l'extérieur de la fonction. Voici un exemple détaillé qui vous guidera à travers ces étapes:
Voir le script ci-dessous en action ici sur jsfiddle
la source
Dans un code, si vous utilisez une variable sans utiliser var, alors ce qui se passe, c'est que var var_name est automatiquement placé dans la portée globale, par exemple:
la source
Outre le problème des portées, certaines personnes mentionnent également le levage , mais personne n'a donné d'exemple. En voici une pour la portée mondiale:
la source
Sans utiliser "var", les variables ne peuvent être définies que lorsqu'elles définissent une valeur. Par exemple:
ne peut pas fonctionner dans une portée globale ou toute autre portée . Il doit avoir une valeur comme:
D'un autre côté, vous pouvez définir un vaiable comme;
Sa valeur est
undefined
(Sa valeur n'est pasnull
et elle n'est pas égale ànull
intéressante.).la source
my_var;
est en fait une instruction d'expression valide.my_var;
est une instruction d'expression valide ./my_var;
serait une déclaration invalide. Mais comme je l'ai dit, il s'agit de casuistique grammaticale, je m'excuse, mon commentaire n'était en fait pas approprié.Vous devez utiliser le mot-clé var, sauf si vous avez l'intention d'attacher la variable à l'objet window dans le navigateur. Voici un lien qui explique la portée et la différence entre la portée glocale et la portée locale avec et sans mot-clé var.
Lorsque des variables sont définies sans utiliser le mot clé var, ce à quoi cela ressemble est une simple opération «d'affectation».
Lorsque la valeur est affectée à une variable en javascript, l'interpréteur essaie d'abord de trouver la «déclaration de variable» dans le même contexte / étendue que celui de l'affectation. Lorsque l'interpréteur s'exécute
dummyVariable = 20
, il recherche la déclaration de dummyVariable au début de la fonction. (Puisque toutes les déclarations de variables sont déplacées au début du contexte par un interpréteur javascript et cela s'appelle le levage)Vous pouvez également regarder le levage en javascript
la source