web-dev-qa-db-fra.com

Quel est le but du mot-clé var et quand devrais-je l'utiliser (ou l'omettre)?

NOTE: Cette question a été posée du point de vue de la version 3 d'ECMAScript 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 mot clé var 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?

1490
Alex

Si vous êtes dans le monde entier, il n'y a pas beaucoup de différence. Lire Kangax réponse pour explication

Si vous êtes dans une fonction, alors var créera une variable locale, "no var" recherchera la chaîne de portées jusqu'à ce qu'elle trouve la variable ou atteigne la portée globale pointez il va le créer):

// These are both globals
var foo = 1;
bar = 2;

function()
{
    var foo = 1; // Local
    bar = 2;     // Global

    // Execute an anonymous function
    (function()
    {
        var wibble = 1; // Local
        foo = 2; // Inherits from scope above (creating a closure)
        moo = 3; // Global
    }())
}

Si vous ne faites pas d'affectation, vous devez utiliser var:

var x; // Declare x
1315
Greg

Il y a une différence .

var x = 1 déclare la variable x dans la portée actuelle (ou contexte d'exécution). Si la déclaration apparaît dans une fonction - une variable locale est déclarée; si c'est dans la portée globale - une variable globale est déclarée.

x = 1, d'autre part, est simplement une cession de propriété. Il essaie d’abord de résoudre x contre la chaîne d’étendue. S'il le trouve n'importe où dans cette chaîne d'étendue, il effectue une affectation. si elle ne trouve pas x, alors seulement elle crée la propriété x sur un objet global (qui est un top objet de niveau dans une chaîne d'étendue).

Notez maintenant 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 prêter à confusion à moins de comprendre que les déclarations de variable créent également des propriétés (uniquement sur un objet Variable) et que chaque propriété de Javascript (bien, ECMAScript) ont certains drapeaux 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 et x = 1 (lorsqu’elle est exécutée dans une portée globale) est que l’ancienne - déclaration de variable - crée la propriété DontDelete'able, et la dernière ne le fait pas En conséquence, la propriété créée via cette affectation implicite peut ensuite être supprimée de l'objet global et l'ancien objet, celui créé via la déclaration de variable, ne peut pas être supprimé.

Mais ceci n’est que théorie, bien sûr, et dans la pratique, il existe encore plus de différences entre les deux , en raison de divers bugs dans les implémentations (telles que celles de IE ).

J'espère que tout a du sens :)


[Mise à jour 2010/12/16]

Dans ES5 (ECMAScript 5; 5ème édition du langage récemment normalisée), il existe un "mode strict" - un mode de langage opt-in, qui modifie légèrement le comportement des assignations non déclarées. En mode strict, l'affectation à un identifiant non déclaré est une erreur de référence (== --- ==) . La raison en était d’attraper les assignations accidentelles, empêchant la création de propriétés globales non désirées. Certains des nouveaux navigateurs ont déjà commencé à prendre en charge le mode strict. Voir, par exemple, ma table compat .

724
kangax

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 penser à cela comme la différence entre "local et le plus proche". Le plus proche peut sûrement être mondial, mais ce ne sera pas toujours le cas.

/* global scope */
var local = true;
var global = true;

function outer() {
    /* local scope */
    var local = true;
    var global = false;

    /* nearest scope = outer */
    local = !global;

    function inner() {
        /* nearest scope = outer */
        local = false;
        global = false;

        /* nearest scope = undefined */
        /* defaults to defining a global */
        public = global;
    }
}
133
Jonathan Lonowski

Lorsque Javascript est exécuté dans un navigateur, tout votre code est entouré d'une instruction with, comme ceci:

with (window) {
    //Your code
}

Plus d'infos sur with - MDN

Puisque var déclare une variable dans la portée actuelle , il n'y a pas de différence entre déclarer var à l'intérieur de la fenêtre et ne pas le déclarer du tout.

La différence vient 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.

Utiliser var vous permet de masquer les 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 empirique consiste à toujours utiliser var, car vous risqueriez sinon d'introduire des bogues subtils.

EDIT: Après les critiques que j'ai reçues, je voudrais souligner les points suivants:

  • var déclare une variable dans la portée actuelle
  • La portée globale est window
  • Ne pas utiliser var déclare implicitement var dans la portée globale (fenêtre)
  • Déclarer une variable dans la portée globale (fenêtre) à l'aide de var revient à l'omettre.
  • Déclarer une variable dans les portées différente de window en utilisant var n'est pas la même chose que de déclarer une variable sans var
  • Déclarez toujours var explicitement car c'est une bonne pratique
78
kentaromiura

Vous devez toujours utiliser le mot clé var pour déclarer des variables. Pourquoi? Une bonne pratique de codage devrait être une raison suffisante en soi, mais déclarer une variable sans le mot clé var signifie que cette dernière est déclarée dans la portée globale (une variable comme celle-ci s'appelle un global "implicite"). Douglas Crockford recommande de ne jamais utiliser de globes implicites , et conformément aux directives de codage JavaScript d'Apple :

Toute variable créée sans le mot clé var est créée à l’étendue globale et ne fait pas l’objet d’une ordure lors du retour de la fonction (car elle n’est pas hors de portée), ce qui présente l’occasion d’une fuite de mémoire.

En résumé, déclarez toujours les variables à l’aide du mot clé var.

39
Steve Harrison

Voici un bon exemple de la façon dont vous pouvez être surpris en évitant de déclarer des variables locales avec var:

<script>
one();

function one()
{
    for (i = 0;i < 10;i++)
    {
        two();
        alert(i);
    }
}

function two()
{
    i = 1;
}
</script>

(i est réinitialisé à chaque itération de la boucle, car il n'est pas déclaré localement dans la boucle for mais globalement), ce qui aboutit à une boucle infinie

28
Chris S

Je dirais qu'il vaut mieux 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, celle-ci aura une portée globale.

Pour plus d'informations, vous pouvez lancer une recherche sur "Chaîne d'étendue JavaScript" dans Google.

11
Billy

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 en tant que tel.

Utilisez const et let

const doit être utilisé dans 95% des cas. Cela fait en sorte que la référence de variable ne puisse pas changer, ainsi les propriétés de tableau, d'objet et de nœud DOM peuvent changer et devraient probablement être const.

let devrait être utilisé pour toute variable devant être réaffectée. Cela inclut dans une boucle for. Si vous écrivez déjà varName = au-delà de l'initialisation, utilisez let.

Les deux ont une portée au niveau du bloc, comme prévu dans la plupart des autres langues.

9
Gibolt

Sans var - variable globale.

Fortement recommandé de TOUJOURS utiliser l'instruction var, car init variable globale dans un contexte local - est mauvais. Mais, si vous avez besoin de ce sale tour, vous devriez écrire un commentaire au début de la page:

/* global: varname1, varname2... */
8
Anatoliy

une autre différence, par exemple

var a = a || [] ; // works 

tandis que

a = a || [] ; // a is undefined error.
8
Pranay Warke

L'utilisation de var est toujours une bonne idée pour éviter que les variables n'encombrent la portée globale et que les variables n'entrent en conflit, ce qui entraîne un écrasement indésirable.

7
kevinji

@Chris S a donné un bel exemple illustrant la différence pratique (et le danger) entre var et non var. En voici un autre. Je trouve celui-ci particulièrement dangereux car la différence n'est visible que dans un environnement asynchrone, de sorte qu'elle peut facilement passer inaperçue lors des tests.

Comme vous vous en doutez, les extraits de code suivants ["text"]:

function var_fun() {
  let array = []
  array.Push('text')
  return array
}

console.log(var_fun())

L'extrait suivant fait de même (notez le let manquant avant array):

function var_fun() {
  array = []
  array.Push('text')
  return array
}

console.log(var_fun())

L'exécution asynchrone de la manipulation des données produit toujours le même résultat avec un seul exécuteur:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.Push('text')
    return array
  })
}

var_fun().then(result => {console.log(result)})

Mais se comporte différemment avec plusieurs:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.Push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})

Utilisant laisser cependant:

function var_fun() {
  let array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.Push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})
2
thisismydesign

Voici un exemple de code que j'ai écrit pour que vous compreniez ce concept:

var foo = 5; 
bar = 2;     
fooba = 3;

// Execute an anonymous function
(function() {    
    bar = 100;             //overwrites global scope bar
    var foo = 4;           //a new foo variable is created in this' function's scope
    var fooba = 900;       //same as above
    document.write(foo);   //prints 4
    document.write(bar);   //prints 100
    document.write(fooba); //prints 900
})();

document.write('<br/>');
document.write('<br/>');
document.write(foo);       //prints 5
document.write(bar);       //prints 100
document.write(fooba);     //prints 3
2
newday

Je vois des gens confus lors de la déclaration de variables avec ou sans var et à l'intérieur ou à l'extérieur de la fonction. Voici un exemple profond qui vous guidera à travers ces étapes:

Voir le script ci-dessous en action ici à jsfiddle

a = 1;// Defined outside the function without var
var b = 1;// Defined outside the function with var
alert("Starting outside of all functions... \n \n a, b defined but c, d not defined yet: \n a:" + a + "\n b:" + b + "\n \n (If I try to show the value of the undefined c or d, console.log would throw 'Uncaught ReferenceError: c is not defined' error and script would stop running!)");

function testVar1(){
    c = 1;// Defined inside the function without var
    var d = 1;// Defined inside the function with var
    alert("Now inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};


testVar1();
alert("Run the 1. function again...");
testVar1();

function testVar2(){
    var d = 1;// Defined inside the function with var
    alert("Now inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};

testVar2();

alert("Now outside of all functions... \n \n Final Values: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n You will not be able to see d here because then the value is requested, console.log would throw error 'Uncaught ReferenceError: d is not defined' and script would stop. \n ");
alert("**************\n Conclusion \n ************** \n \n 1. No matter declared with or without var (like a, b) if they get their value outside the function, they will preserve their value and also any other values that are added inside various functions through the script are preserved.\n 2. If the variable is declared without var inside a function (like c), it will act like the previous rule, it will preserve its value across all functions from now on. Either it got its first value in function testVar1() it still preserves the value and get additional value in function testVar2() \n 3. If the variable is declared with var inside a function only (like d in testVar1 or testVar2) it will will be undefined whenever the function ends. So it will be temporary variable in a function.");
alert("Now check console.log for the error when value d is requested next:");
alert(d);

Conclusion

  1. Quel que soit le sujet déclaré avec ou sans var (comme a, b), s’ils obtiennent leur valeur en dehors de la fonction, ils conservent leur valeur et toutes les autres valeurs ajoutées dans diverses fonctions par le biais du script sont préservées.
  2. Si la variable est déclarée sans var dans une fonction (comme c), elle agira comme la règle précédente, elle conservera désormais sa valeur dans toutes les fonctions. Soit il a obtenu sa première valeur dans la fonction testVar1 (), il conserve toujours la valeur et obtient une valeur supplémentaire dans la fonction testVar2 ()
  3. Si la variable est déclarée avec var dans une fonction uniquement (comme d dans testVar1 ou testVar2), elle sera indéfinie à la fin de la fonction. Donc ce sera une variable temporaire dans une fonction.
1
Tarik

Dans un code, si vous utilisez une variable sans utiliser var, alors ce qui se passe est que var nom_var est automatiquement placé dans la portée globale, par exemple:

someFunction() {
    var a = some_value; /*a has local scope and it cannot be accessed when this
    function is not active*/
    b = a; /*here it places "var b" at top of script i.e. gives b global scope or
    uses already defined global variable b */
}
1
Akash Arora

En tant que quelqu'un essayant d'apprendre ceci, c'est comme ça 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:

var local = true;
var global = true;


function test(){
  var local = false;
  var global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

La sortie se lira comme suit: false, false, true, true

Parce qu'elle considère que les variables de la fonction sont séparées de celles qui se trouvent en dehors de celle-ci, d'où le terme variable locale, c'est parce que nous avons utilisé var dans l'affectation. Si vous supprimez la var dans la fonction, elle se lit maintenant comme ceci:

var local = true;
var global = true;


function test(){
  local = false;
  global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

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.

0
Danrex

Vous devez utiliser le mot-clé var sauf si vous avez l'intention d'associer la variable à l'objet window dans le navigateur. Voici un lien qui explique la portée et la différence entre la portée glocal et la portée locale avec et sans mot clé var.

Lorsque les variables sont définies sans utiliser le mot-clé var, il s’agit d’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/la même portée que celui de l'affectation. Lorsque l'interprète exécute dummyVariable = 20, il recherche la déclaration de dummyVariable au début de la fonction. (Puisque toutes les déclarations de variable sont déplacées au début du contexte par un interpréteur javascript, on parle de levage)

Vous voudrez peut-être aussi regarder levage en javascript

0
Simran kaur

Sans utiliser "var", les variables ne peuvent définir que lorsqu'une valeur est définie. Par exemple:

my_var;

ne peut pas fonctionner dans portée globale ou toute autre portée. Il devrait être avec une valeur comme:

my_var = "value";

D'autre part, vous pouvez définir un vaiable comme;

var my_var;

Sa valeur est undefined (sa valeur n'est pas null et elle n'est pas égale à null de manière intéressante.).

0
umut