What is the purpose of the var keyword and when should I use it (or omit it)?
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.
在javascript中,
1 2 3 4 | var someNumber = 2; var someFunction = function() { doSomething; } var someObject = { } var someObject.someProperty = 5; |
和
1 2 3 4 | someNumber = 2; someFunction = function() { doSomething; } someObject = { } someObject.someProperty = 5; |
?
你什么时候用其中一个,为什么用它?
如果你在全球范围内,那么没有什么区别。读康克斯的答案来解释
如果您在函数中,那么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 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 }()) } |
如果您不执行任务,则需要使用
1 | var x; // Declare x |
有区别。
另一方面,
现在,注意它不声明全局变量,而是创建一个全局属性。
这两者之间的区别是微妙的,可能会令人困惑,除非您了解变量声明也创建属性(仅在变量对象上),并且javascript中的每个属性(好的,ecmascript)都有一些描述其属性的标志-readonly、dontenum和dontDelete。
由于variable声明使用dontDelete标志创建属性,因此
但这当然只是理论上的,而且在实践中,由于实现中的各种错误(例如来自IE的错误),两者之间甚至存在更多的差异。
希望一切都有意义:)
[更新2010/12/16]
在ES5(ECMAScript 5;最近标准化,第五版语言)中,有一种所谓的"严格模式"——一种选择性语言模式,它稍微改变了未声明的作业的行为。在严格模式下,对未声明标识符的赋值是引用错误。其基本原理是捕获意外分配,防止创建不需要的全局属性。一些较新的浏览器已经开始滚动支持严格模式。例如,请参见my compat表。
说"本地"和"全球"的区别并不完全准确。
最好把它看成是"局部"和"最近"之间的区别。最近的肯定是全球性的,但情况并非总是如此。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* 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; } } |
在浏览器中执行javascript时,所有代码都被一个WITH语句包围,如下所示:
1 2 3 | with (window) { //Your code } |
更多有关
由于
当您不直接在窗口中时(例如,在函数内部或在块内部),就会产生差异。
使用
经验法则是始终使用
编辑:在收到我的评论后,我想强调以下几点:
var 声明了当前作用域中的变量- 全球范围是
window 。 - 不使用
var 在全局范围(window)中隐式声明var 。 - 使用
var 在全局范围(窗口)中声明变量与省略变量相同。 - 在不同于使用
var 的窗口的范围中声明变量与声明不使用var 的变量不同。 - 务必明确声明
var ,因为这是良好的做法
应该始终使用
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.
因此,简而言之,总是使用
下面是一个很好的例子,说明如何避免使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | one(); function one() { for (i = 0;i < 10;i++) { two(); alert(i); } } function two() { i = 1; } |
(
我想说在大多数情况下最好使用
局部变量总是比全局范围内的变量快。
如果不使用
更多信息,你可以在谷歌搜索"范围链javascript"。
不带
强烈建议始终使用
1 | /* global: varname1, varname2... */ |
另一个区别例如
1 | var a = a || [] ; // works |
虽然
1 | a = a || [] ; // a is undefined error. |
使用
不要使用
95%的病例应使用
对于希望重新分配的变量,应使用
正如大多数其他语言所预期的那样,这两种语言都具有块级作用域。
这是我为您编写的用于理解此概念的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
@Chris S给出了一个很好的例子,展示了
正如您所期望的,下面的代码片段将输出
1 2 3 4 5 6 7 | function var_fun() { let array = [] array.push('text') return array } console.log(var_fun()) |
下面的代码片段也是如此(注意在
1 2 3 4 5 6 7 | function var_fun() { array = [] array.push('text') return array } console.log(var_fun()) |
异步执行数据操作仍然会产生与单个执行器相同的结果:
1 2 3 4 5 6 7 8 9 | function var_fun() { array = []; return new Promise(resolve => resolve()).then(() => { array.push('text') return array }) } var_fun().then(result => {console.log(result)}) |
但在多个方面表现不同:
1 2 3 4 5 6 7 8 9 10 11 | 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)}) }) |
但是,使用let:
1 2 3 4 5 6 7 8 9 10 11 | 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)}) }) |
在代码中,如果使用变量而不使用var,则会自动将var var_名称放在全局范围中,例如:
1 2 3 4 5 6 | 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 */ } |
如果不使用"var",变量只能在设置值时定义。例如:
1 | my_var; |
无法在全局范围或任何其他范围内工作。它的值应该是:
1 | my_var ="value"; |
另一方面,你可以定义一个可用的类;
1 | var my_var; |
它的值是
当一些人试图了解这一点时,这就是我所看到的。对于初学者来说,上面的例子可能有点过于复杂。
如果运行此代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); |
输出将读取为:假、假、真、真
因为它认为函数中的变量与它外部的变量是分开的,所以术语局部变量,这是因为我们在赋值中使用了var。如果去掉函数中的var,那么它现在的读数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); |
输出为假、假、假、假
这是因为它不在本地范围或函数中创建新的变量,而只是使用全局变量并将其重新分配为false。
我看到,当声明变量时,无论有无var,函数内部还是外部,人们都会感到困惑。下面是一个深入的例子,将引导您完成以下步骤:
请参阅下面在jsfiddle中的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | a = 1;// Defined outside the function without var var b = 1;// Defined outside the function with var alert("Starting outside of all functions... a, b defined but c, d not defined yet: a:" + a +" b:" + b +" (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: a:" + a +" b:" + b +" c:" + c +" d:" + d); a = a + 5; b = b + 5; c = c + 5; d = d + 5; alert("After added values inside the 1. function: a:" + a +" b:" + b +" c:" + c +" 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: a:" + a +" b:" + b +" c:" + c +" d:" + d); a = a + 5; b = b + 5; c = c + 5; d = d + 5; alert("After added values inside the 2. function: a:" + a +" b:" + b +" c:" + c +" d:" + d); }; testVar2(); alert("Now outside of all functions... Final Values: a:" + a +" b:" + b +" c:" + c +" 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. "); alert("************** 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. 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() 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
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. 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() 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.
您应该使用var关键字,除非您希望将变量附加到浏览器中的window对象。这是一个链接,解释了使用和wihtout var关键字的范围界定和本地范围界定之间的区别。
当不使用var关键字定义变量时,它看起来像是一个简单的"赋值"操作。
当该值在javascript中分配给变量时,解释器首先尝试在与赋值相同的上下文/范围中查找"变量声明"。当解释器执行
您可能还想看看JavaScript中的提升