var关键字的目的是什么?我应该何时使用它(或省略它)?

时间:2022-09-10 23:19:23

NOTE: This question was asked from the viewpoint of ECMAScript version 3 or 5. The answers might become outdated with the introduction of new features in the release of ECMAScript 6.

注意:这个问题是从ECMAScript版本3或5的角度提出的。随着ECMAScript 6发布的新特性的引入,答案可能会过时。

What exactly is the function of the var keyword in JavaScript, and what is the difference between

在JavaScript中,var关键字的功能到底是什么

var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;

and

someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;

?

吗?

When would you use either one, and why/what does it do?

你什么时候用哪一种,为什么用哪一种?

18 个解决方案

#1


1246  

If you're in the global scope then there's no difference.

如果你在全局范围内,那么没有区别。

If you're in a function then var will create a local variable, "no var" will look up the scope chain until it finds the variable or hits the global scope (at which point it will create it):

如果您在一个函数中,那么var将创建一个局部变量,“no var”将查找范围链,直到找到该变量或到达全局范围(这时它将创建它):

// 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
    }())
}

If you're not doing an assignment then you need to use var:

如果你不做作业,那么你需要使用var:

var x; // Declare x

#2


693  

There's a difference.

有一个区别。

var x = 1 declares variable x in current scope (aka execution context). If the declaration appears in a function - a local variable is declared; if it's in global scope - a global variable is declared.

var x = 1在当前范围(即执行上下文)中声明变量x。如果声明出现在函数中,则声明局部变量;如果它在全局范围内,则声明一个全局变量。

x = 1, on the other hand, is merely a property assignment. It first tries to resolve x against scope chain. If it finds it anywhere in that scope chain, it performs assignment; if it doesn't find x, only then does it creates x property on a global object (which is a top level object in a scope chain).

另一方面,x = 1只是一个属性赋值。它首先尝试针对范围链解析x。如果它在范围链的任何地方找到它,它就执行赋值;如果它没有找到x,那么只有在全局对象(作用域链中的*对象)上创建x属性。

Now, notice that it doesn't declare a global variable, it creates a global property.

注意,它没有声明全局变量,而是创建一个全局属性。

The difference between the two is subtle and might be confusing unless you understand that variable declarations also create properties (only on a Variable Object) and that every property in Javascript (well, ECMAScript) have certain flags that describe their properties - ReadOnly, DontEnum and DontDelete.

两者之间的区别是微妙的,而且可能会令人困惑,除非您理解变量声明也创建属性(仅在一个变量对象上),并且Javascript中的每个属性(好吧,ECMAScript)都有描述其属性的特定标志——ReadOnly、DontEnum和DontDelete。

Since variable declaration creates property with the DontDelete flag, the difference between var x = 1 and x = 1 (when executed in global scope) is that the former one - variable declaration - creates the DontDelete'able property, and latter one doesn't. As a consequence, the property created via this implicit assignment can then be deleted from the global object, and the former one - the one created via variable declaration - cannot be deleted.

由于变量声明使用DontDelete标志创建属性,所以var x = 1和x = 1(在全局范围中执行时)之间的区别在于,前面的一个变量声明创建DontDelete'able属性,而后面的一个则不创建。因此,通过这个隐式赋值创建的属性可以从全局对象中删除,而前一个属性(通过变量声明创建的)不能被删除。

But this is just theory of course, and in practice there are even more differences between the two, due to various bugs in implementations (such as those from IE).

但这只是理论上的,实际上两者之间的差异更大,因为实现中的各种bug(比如IE中的bug)。

Hope it all makes sense : )

希望这一切都是有意义的。


[Update 2010/12/16]

(更新2010/12/16)

In ES5 (ECMAScript 5; recently standardized, 5th edition of the language) there's a so-called "strict mode" — an opt-in language mode, which slightly changes the behavior of undeclared assignments. In strict mode, assignment to an undeclared identifier is a ReferenceError. The rationale for this was to catch accidental assignments, preventing creation of undesired global properties. Some of the newer browsers have already started rolling support for strict mode. See, for example, my compat table.

在ES5(ECMAScript 5;最近标准化的,第五版的语言)有一个所谓的“严格模式”——一种选择的语言模式,它稍微改变了未声明的任务的行为。在严格模式下,给未声明的标识符赋值是一个引用错误。这样做的基本原理是捕获意外分配,防止创建不希望的全局属性。一些较新的浏览器已经开始支持严格模式。看,例如,我的compat表。

#3


129  

Saying it's the difference between "local and global" isn't entirely accurate.

说这是“本地和全球”之间的区别并不完全准确。

It might be better to think of it as the difference between "local and nearest". The nearest can surely be global, but that won't always be the case.

最好把它看成是“局部的”和“最近的”的区别。最近的肯定是全球性的,但并非总是如此。

/* 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;
    }
}

#4


76  

When Javascript is executed in a browser, all your code is surrounded by a with statement, like so:

当Javascript在浏览器中执行时,所有代码都被一个带有语句的语句包围,比如:

with (window) {
    //Your code
}

More info on with - MDN

更多信息与- MDN

Since var declares a variable in the current scope , there is no difference between declaring var inside window and not declaring it at all.

由于var在当前范围内声明了一个变量,所以在窗口内声明var和根本不声明它之间没有区别。

The difference comes when you're not directly inside the window, e.g. inside a function or inside a block.

当你不在窗口内时,比如在函数内或在块内,就会产生差异。

Using var lets you hide external variables that have the same name. In this way you can simulate a "private" variable, but that's another topic.

使用var可以隐藏具有相同名称的外部变量。通过这种方式,您可以模拟一个“私有”变量,但这是另一个主题。

A rule of thumb is to always use var, because otherwise you run the risk of introducing subtle bugs.

一个经验法则是始终使用var,否则您将面临引入细微bug的风险。

EDIT: After the critiques I received, I would like to emphasize the following:

编辑:在收到评论后,我想强调以下几点:

  • var declares a variable in the current scope
  • var在当前范围中声明一个变量
  • The global scope is window
  • 全局范围是窗口
  • Not using var implicitly declares var in the global scope (window)
  • 在全局范围(窗口)中不使用var隐式声明var
  • Declaring a variable in the global scope (window) using var is the same as omitting it.
  • 使用var在全局范围(窗口)中声明一个变量与删除它是一样的。
  • Declaring a variable in scopes different from window using var is not the same thing as declaring a variable without var
  • 在不同的窗口中使用var声明一个变量与声明一个没有var的变量是不一样的。
  • Always declare var explicitly because it's good practice
  • 总是显式地声明var,因为这是很好的实践

#5


37  

You should always use the var keyword to declare variables. Why? Good coding practice should be enough of a reason in itself, but declaring a variable without the var keyword means it is declared in the global scope (a variable like this is called an "implied" global). Douglas Crockford recommends never using implied globals, and according to the Apple JavaScript Coding Guidelines:

您应该始终使用var关键字来声明变量。为什么?良好的编码实践本身应该是足够的理由,但是声明一个没有var关键字的变量意味着它是在全局范围中声明的(像这样的变量称为“隐含的”全局)。Douglas Crockford建议不要使用隐含的全局变量,并且根据苹果JavaScript代码指南:

Any variable created without the var keyword is created at the global scope and is not garbage collected when the function returns (because it doesn’t go out of scope), presenting the opportunity for a memory leak.

不使用var关键字创建的任何变量都是在全局作用域中创建的,并且在函数返回时不会被垃圾收集(因为它不会超出作用域),从而导致内存泄漏。

So, in short, always declare variables using the var keyword.

因此,简而言之,总是使用var关键字声明变量。

#6


27  

Here's quite a good example of how you can get caught out from not declaring local variables with var:

这里有一个很好的例子,说明了如何通过不使用var声明局部变量而被捕获:

<script>
one();

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

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

(i is reset at every iteration of the loop, as it's not declared locally in the for loop but globally) eventually resulting in infinite loop

(在循环的每一个迭代中,我都会重置,因为它不是在for循环中本地声明的,而是全局的)最终导致了无限循环。

#7


12  

I would say it's better to use var in most situations.

我认为在大多数情况下最好使用var。

Local variables are always faster than the variables in global scope.

局部变量总是比全局范围中的变量快。

If you do not use var to declare a variable, the variable will be in global scope.

如果不使用var来声明变量,则该变量将处于全局范围内。

For more information, you can search "scope chain JavaScript" in Google.

要了解更多信息,可以在谷歌中搜索“范围链JavaScript”。

#8


8  

another difference e.g

另一个区别如

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

while

a = a || [] ; // a is undefined error.

#9


7  

Using var is always a good idea to prevent variables from cluttering the global scope and variables from conflicting with each other, causing unwanted overwriting.

使用var始终是一个好主意,可以防止变量将全局范围和变量相互冲突,导致不必要的覆盖。

#10


7  

Without var - global variable.

没有var -全局变量。

Strongly recommended to ALWAYS use var statement, because init global variable in local context - is evil. But, if you need this dirty trick, you should write comment at start of page:

强烈建议始终使用var语句,因为init全局变量在本地上下文中是有害的。但是,如果你需要这个卑鄙的伎俩,你应该在开头写评论:

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

#11


4  

Don't use var!

var was the pre-ES6 way to declare a variable. We are now in the future, and you should be coding as such.

var是es6之前声明变量的方法。我们现在是在未来,你应该这样编码。

Use const and let

const should be used for 95% of cases. It makes it so the variable reference can't change, thus array, object, and DOM node properties can change and should likely be const.

95%的病例应使用const。它使变量引用不能更改,因此数组、对象和DOM节点属性可以更改,并且应该是const。

let should be be used for any variable expecting to be reassigned. This includes within a for loop. If you ever write varName = beyond the initialization, use let.

让应该用于任何期望重新分配的变量。这包括在for循环中。如果您曾在初始化之外编写varName =,请使用let。

Both have block level scoping, as expected in most other languages.

这两种语言都具有块级范围,在大多数其他语言中都是如此。

#12


2  

This is example code I have written for you to understand this 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

#13


1  

Inside a code you if you use a variable without using var, then what happens is the automatically var var_name is placed in the global scope eg:

在代码中,如果使用变量而不使用var,那么自动的var var_name将被放置在全局范围中,例如:

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 */
}

#14


0  

Without using "var" variables can only define when set a value. In example:

不使用“var”变量只能定义何时设置一个值。在示例:

my_var;

cannot work in global scope or any other scope. It should be with value like:

不能在全局范围或任何其他范围内工作。它应该具有如下值:

my_var = "value";

On the other hand you can define a vaiable like;

另一方面,你可以定义一个可变的类;

var my_var;

Its value is undefined ( Its value is not null and it is not equal to null interestingly.).

它的值没有定义(它的值不是null,有趣的是它不等于null)。

#15


0  

As someeone trying to learn this this is how I see it. The above examples were maybe a bit overly complicated for a beginner.

当有人试图了解这一点时,这就是我的看法。对于初学者来说,上面的例子可能有点过于复杂。

If you run this 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);

The output will read as: false, false, true, true

输出将读为:false、false、true、true

Because it sees the variables in the function as seperate from those outside of it, hence the term local variable and this was because we used var in the assignment. If you take away the var in the function so it now reads like this:

因为它把函数中的变量与函数外的变量分开,所以是局部变量这是因为我们在赋值中使用了var。如果你把函数中的var去掉,它现在是这样的:

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);

The output is false, false, false, false

输出是false、false、false和false

This is because rather than creating a new variable in the local scope or function it simply uses the global variables and reassigns them to false.

这是因为它没有在本地范围或函数中创建新变量,而是使用全局变量并将其重新赋值为false。

#16


0  

I see people are confused when declaring variables with or without var and inside or outside the function. Here is a deep example that will walk you through these steps:

我看到人们在声明变量是否带有var以及函数内部或外部时感到困惑。这里有一个深刻的例子,将带你走过这些步骤:

See the script below in action here at jsfiddle

请参阅下面在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. 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.
  2. 无论是否声明了var(如a、b),如果它们在函数之外获得了值,它们都将保留它们的值,并且通过脚本在各种函数中添加的任何其他值也将被保留。
  3. 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()
  4. 如果变量在函数(如c)中声明没有var,那么它将像前面的规则一样,从现在开始,它将保持其在所有函数中的值。或者它在函数testVar1()中得到了第一个值它仍然保留了这个值并在函数testVar2()中获得了附加值
  5. 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.
  6. 如果变量仅在函数中声明var(如testVar1中的d或testVar2中的d),那么当函数结束时它将是未定义的。所以它是函数中的临时变量。

#17


0  

You should use var keyword unless you intend to have the variable attached to window object in browser. Here's a link that explains scoping and difference between glocal scoping and local scoping with and wihtout var keyword.

您应该使用var关键字,除非您打算在浏览器中将变量附加到窗口对象。这里有一个链接,解释了使用glocal scoping和使用和wihtout var关键字的本地scoping之间的区别。

When variables get defined without the use of var keyword, what it looks like is a simple “assignment” operation.

当不使用var关键字定义变量时,看起来就像一个简单的“赋值”操作。

When the value is assigned to a variable in javascript, the interpreter first tries to find the “variable declaration” in the same context/scope as that of assignment. When the interpreter executes dummyVariable = 20, it looks up for the declaration of dummyVariable at beginning of the function. (Since all Variable declarations are moved to the beginning of the context by javascript interpreter and this is called hoisting)

当将值分配给javascript中的变量时,解释器首先尝试在与赋值相同的上下文中/范围中找到“变量声明”。当解释器执行dummyVariable = 20时,它会在函数的开头查找dummyVariable的声明。(因为所有的变量声明都被javascript解释器移动到上下文的开头,这被称为提升)

You may also want to look at hoisting in javascript

您可能还想了解如何在javascript中提升

#18


0  

@Chris S gave a nice example showcasing the practical difference (and danger) between var and no var. Here's another one, I find this one particularly dangerous because the difference is only visible in an asynchronous environment so it can easily slip by during testing.

@Chris S给出了一个很好的例子,展示了var和no var之间的实际差异(和危险)。

As you'd expect the following snippet outputs ["text"]:

如您所期望的,以下代码片段输出["text"]:

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

console.log(var_fun())

So does the following snippet (note the missing let before array):

下面的代码片段(注意数组前的缺失):

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

console.log(var_fun())

Executing the data manipulation asynchronously still produces the same result with a single executor:

异步执行数据操作仍然会产生与单个执行程序相同的结果:

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

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

But behaves differently with multiple ones:

但不同的是,它们的行为是不同的:

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)})
})

Using let however:

然而使用让:

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)})
})

#1


1246  

If you're in the global scope then there's no difference.

如果你在全局范围内,那么没有区别。

If you're in a function then var will create a local variable, "no var" will look up the scope chain until it finds the variable or hits the global scope (at which point it will create it):

如果您在一个函数中,那么var将创建一个局部变量,“no var”将查找范围链,直到找到该变量或到达全局范围(这时它将创建它):

// 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
    }())
}

If you're not doing an assignment then you need to use var:

如果你不做作业,那么你需要使用var:

var x; // Declare x

#2


693  

There's a difference.

有一个区别。

var x = 1 declares variable x in current scope (aka execution context). If the declaration appears in a function - a local variable is declared; if it's in global scope - a global variable is declared.

var x = 1在当前范围(即执行上下文)中声明变量x。如果声明出现在函数中,则声明局部变量;如果它在全局范围内,则声明一个全局变量。

x = 1, on the other hand, is merely a property assignment. It first tries to resolve x against scope chain. If it finds it anywhere in that scope chain, it performs assignment; if it doesn't find x, only then does it creates x property on a global object (which is a top level object in a scope chain).

另一方面,x = 1只是一个属性赋值。它首先尝试针对范围链解析x。如果它在范围链的任何地方找到它,它就执行赋值;如果它没有找到x,那么只有在全局对象(作用域链中的*对象)上创建x属性。

Now, notice that it doesn't declare a global variable, it creates a global property.

注意,它没有声明全局变量,而是创建一个全局属性。

The difference between the two is subtle and might be confusing unless you understand that variable declarations also create properties (only on a Variable Object) and that every property in Javascript (well, ECMAScript) have certain flags that describe their properties - ReadOnly, DontEnum and DontDelete.

两者之间的区别是微妙的,而且可能会令人困惑,除非您理解变量声明也创建属性(仅在一个变量对象上),并且Javascript中的每个属性(好吧,ECMAScript)都有描述其属性的特定标志——ReadOnly、DontEnum和DontDelete。

Since variable declaration creates property with the DontDelete flag, the difference between var x = 1 and x = 1 (when executed in global scope) is that the former one - variable declaration - creates the DontDelete'able property, and latter one doesn't. As a consequence, the property created via this implicit assignment can then be deleted from the global object, and the former one - the one created via variable declaration - cannot be deleted.

由于变量声明使用DontDelete标志创建属性,所以var x = 1和x = 1(在全局范围中执行时)之间的区别在于,前面的一个变量声明创建DontDelete'able属性,而后面的一个则不创建。因此,通过这个隐式赋值创建的属性可以从全局对象中删除,而前一个属性(通过变量声明创建的)不能被删除。

But this is just theory of course, and in practice there are even more differences between the two, due to various bugs in implementations (such as those from IE).

但这只是理论上的,实际上两者之间的差异更大,因为实现中的各种bug(比如IE中的bug)。

Hope it all makes sense : )

希望这一切都是有意义的。


[Update 2010/12/16]

(更新2010/12/16)

In ES5 (ECMAScript 5; recently standardized, 5th edition of the language) there's a so-called "strict mode" — an opt-in language mode, which slightly changes the behavior of undeclared assignments. In strict mode, assignment to an undeclared identifier is a ReferenceError. The rationale for this was to catch accidental assignments, preventing creation of undesired global properties. Some of the newer browsers have already started rolling support for strict mode. See, for example, my compat table.

在ES5(ECMAScript 5;最近标准化的,第五版的语言)有一个所谓的“严格模式”——一种选择的语言模式,它稍微改变了未声明的任务的行为。在严格模式下,给未声明的标识符赋值是一个引用错误。这样做的基本原理是捕获意外分配,防止创建不希望的全局属性。一些较新的浏览器已经开始支持严格模式。看,例如,我的compat表。

#3


129  

Saying it's the difference between "local and global" isn't entirely accurate.

说这是“本地和全球”之间的区别并不完全准确。

It might be better to think of it as the difference between "local and nearest". The nearest can surely be global, but that won't always be the case.

最好把它看成是“局部的”和“最近的”的区别。最近的肯定是全球性的,但并非总是如此。

/* 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;
    }
}

#4


76  

When Javascript is executed in a browser, all your code is surrounded by a with statement, like so:

当Javascript在浏览器中执行时,所有代码都被一个带有语句的语句包围,比如:

with (window) {
    //Your code
}

More info on with - MDN

更多信息与- MDN

Since var declares a variable in the current scope , there is no difference between declaring var inside window and not declaring it at all.

由于var在当前范围内声明了一个变量,所以在窗口内声明var和根本不声明它之间没有区别。

The difference comes when you're not directly inside the window, e.g. inside a function or inside a block.

当你不在窗口内时,比如在函数内或在块内,就会产生差异。

Using var lets you hide external variables that have the same name. In this way you can simulate a "private" variable, but that's another topic.

使用var可以隐藏具有相同名称的外部变量。通过这种方式,您可以模拟一个“私有”变量,但这是另一个主题。

A rule of thumb is to always use var, because otherwise you run the risk of introducing subtle bugs.

一个经验法则是始终使用var,否则您将面临引入细微bug的风险。

EDIT: After the critiques I received, I would like to emphasize the following:

编辑:在收到评论后,我想强调以下几点:

  • var declares a variable in the current scope
  • var在当前范围中声明一个变量
  • The global scope is window
  • 全局范围是窗口
  • Not using var implicitly declares var in the global scope (window)
  • 在全局范围(窗口)中不使用var隐式声明var
  • Declaring a variable in the global scope (window) using var is the same as omitting it.
  • 使用var在全局范围(窗口)中声明一个变量与删除它是一样的。
  • Declaring a variable in scopes different from window using var is not the same thing as declaring a variable without var
  • 在不同的窗口中使用var声明一个变量与声明一个没有var的变量是不一样的。
  • Always declare var explicitly because it's good practice
  • 总是显式地声明var,因为这是很好的实践

#5


37  

You should always use the var keyword to declare variables. Why? Good coding practice should be enough of a reason in itself, but declaring a variable without the var keyword means it is declared in the global scope (a variable like this is called an "implied" global). Douglas Crockford recommends never using implied globals, and according to the Apple JavaScript Coding Guidelines:

您应该始终使用var关键字来声明变量。为什么?良好的编码实践本身应该是足够的理由,但是声明一个没有var关键字的变量意味着它是在全局范围中声明的(像这样的变量称为“隐含的”全局)。Douglas Crockford建议不要使用隐含的全局变量,并且根据苹果JavaScript代码指南:

Any variable created without the var keyword is created at the global scope and is not garbage collected when the function returns (because it doesn’t go out of scope), presenting the opportunity for a memory leak.

不使用var关键字创建的任何变量都是在全局作用域中创建的,并且在函数返回时不会被垃圾收集(因为它不会超出作用域),从而导致内存泄漏。

So, in short, always declare variables using the var keyword.

因此,简而言之,总是使用var关键字声明变量。

#6


27  

Here's quite a good example of how you can get caught out from not declaring local variables with var:

这里有一个很好的例子,说明了如何通过不使用var声明局部变量而被捕获:

<script>
one();

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

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

(i is reset at every iteration of the loop, as it's not declared locally in the for loop but globally) eventually resulting in infinite loop

(在循环的每一个迭代中,我都会重置,因为它不是在for循环中本地声明的,而是全局的)最终导致了无限循环。

#7


12  

I would say it's better to use var in most situations.

我认为在大多数情况下最好使用var。

Local variables are always faster than the variables in global scope.

局部变量总是比全局范围中的变量快。

If you do not use var to declare a variable, the variable will be in global scope.

如果不使用var来声明变量,则该变量将处于全局范围内。

For more information, you can search "scope chain JavaScript" in Google.

要了解更多信息,可以在谷歌中搜索“范围链JavaScript”。

#8


8  

another difference e.g

另一个区别如

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

while

a = a || [] ; // a is undefined error.

#9


7  

Using var is always a good idea to prevent variables from cluttering the global scope and variables from conflicting with each other, causing unwanted overwriting.

使用var始终是一个好主意,可以防止变量将全局范围和变量相互冲突,导致不必要的覆盖。

#10


7  

Without var - global variable.

没有var -全局变量。

Strongly recommended to ALWAYS use var statement, because init global variable in local context - is evil. But, if you need this dirty trick, you should write comment at start of page:

强烈建议始终使用var语句,因为init全局变量在本地上下文中是有害的。但是,如果你需要这个卑鄙的伎俩,你应该在开头写评论:

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

#11


4  

Don't use var!

var was the pre-ES6 way to declare a variable. We are now in the future, and you should be coding as such.

var是es6之前声明变量的方法。我们现在是在未来,你应该这样编码。

Use const and let

const should be used for 95% of cases. It makes it so the variable reference can't change, thus array, object, and DOM node properties can change and should likely be const.

95%的病例应使用const。它使变量引用不能更改,因此数组、对象和DOM节点属性可以更改,并且应该是const。

let should be be used for any variable expecting to be reassigned. This includes within a for loop. If you ever write varName = beyond the initialization, use let.

让应该用于任何期望重新分配的变量。这包括在for循环中。如果您曾在初始化之外编写varName =,请使用let。

Both have block level scoping, as expected in most other languages.

这两种语言都具有块级范围,在大多数其他语言中都是如此。

#12


2  

This is example code I have written for you to understand this 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

#13


1  

Inside a code you if you use a variable without using var, then what happens is the automatically var var_name is placed in the global scope eg:

在代码中,如果使用变量而不使用var,那么自动的var var_name将被放置在全局范围中,例如:

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 */
}

#14


0  

Without using "var" variables can only define when set a value. In example:

不使用“var”变量只能定义何时设置一个值。在示例:

my_var;

cannot work in global scope or any other scope. It should be with value like:

不能在全局范围或任何其他范围内工作。它应该具有如下值:

my_var = "value";

On the other hand you can define a vaiable like;

另一方面,你可以定义一个可变的类;

var my_var;

Its value is undefined ( Its value is not null and it is not equal to null interestingly.).

它的值没有定义(它的值不是null,有趣的是它不等于null)。

#15


0  

As someeone trying to learn this this is how I see it. The above examples were maybe a bit overly complicated for a beginner.

当有人试图了解这一点时,这就是我的看法。对于初学者来说,上面的例子可能有点过于复杂。

If you run this 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);

The output will read as: false, false, true, true

输出将读为:false、false、true、true

Because it sees the variables in the function as seperate from those outside of it, hence the term local variable and this was because we used var in the assignment. If you take away the var in the function so it now reads like this:

因为它把函数中的变量与函数外的变量分开,所以是局部变量这是因为我们在赋值中使用了var。如果你把函数中的var去掉,它现在是这样的:

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);

The output is false, false, false, false

输出是false、false、false和false

This is because rather than creating a new variable in the local scope or function it simply uses the global variables and reassigns them to false.

这是因为它没有在本地范围或函数中创建新变量,而是使用全局变量并将其重新赋值为false。

#16


0  

I see people are confused when declaring variables with or without var and inside or outside the function. Here is a deep example that will walk you through these steps:

我看到人们在声明变量是否带有var以及函数内部或外部时感到困惑。这里有一个深刻的例子,将带你走过这些步骤:

See the script below in action here at jsfiddle

请参阅下面在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. 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.
  2. 无论是否声明了var(如a、b),如果它们在函数之外获得了值,它们都将保留它们的值,并且通过脚本在各种函数中添加的任何其他值也将被保留。
  3. 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()
  4. 如果变量在函数(如c)中声明没有var,那么它将像前面的规则一样,从现在开始,它将保持其在所有函数中的值。或者它在函数testVar1()中得到了第一个值它仍然保留了这个值并在函数testVar2()中获得了附加值
  5. 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.
  6. 如果变量仅在函数中声明var(如testVar1中的d或testVar2中的d),那么当函数结束时它将是未定义的。所以它是函数中的临时变量。

#17


0  

You should use var keyword unless you intend to have the variable attached to window object in browser. Here's a link that explains scoping and difference between glocal scoping and local scoping with and wihtout var keyword.

您应该使用var关键字,除非您打算在浏览器中将变量附加到窗口对象。这里有一个链接,解释了使用glocal scoping和使用和wihtout var关键字的本地scoping之间的区别。

When variables get defined without the use of var keyword, what it looks like is a simple “assignment” operation.

当不使用var关键字定义变量时,看起来就像一个简单的“赋值”操作。

When the value is assigned to a variable in javascript, the interpreter first tries to find the “variable declaration” in the same context/scope as that of assignment. When the interpreter executes dummyVariable = 20, it looks up for the declaration of dummyVariable at beginning of the function. (Since all Variable declarations are moved to the beginning of the context by javascript interpreter and this is called hoisting)

当将值分配给javascript中的变量时,解释器首先尝试在与赋值相同的上下文中/范围中找到“变量声明”。当解释器执行dummyVariable = 20时,它会在函数的开头查找dummyVariable的声明。(因为所有的变量声明都被javascript解释器移动到上下文的开头,这被称为提升)

You may also want to look at hoisting in javascript

您可能还想了解如何在javascript中提升

#18


0  

@Chris S gave a nice example showcasing the practical difference (and danger) between var and no var. Here's another one, I find this one particularly dangerous because the difference is only visible in an asynchronous environment so it can easily slip by during testing.

@Chris S给出了一个很好的例子,展示了var和no var之间的实际差异(和危险)。

As you'd expect the following snippet outputs ["text"]:

如您所期望的,以下代码片段输出["text"]:

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

console.log(var_fun())

So does the following snippet (note the missing let before array):

下面的代码片段(注意数组前的缺失):

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

console.log(var_fun())

Executing the data manipulation asynchronously still produces the same result with a single executor:

异步执行数据操作仍然会产生与单个执行程序相同的结果:

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

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

But behaves differently with multiple ones:

但不同的是,它们的行为是不同的:

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)})
})

Using let however:

然而使用让:

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)})
})