首页 文章

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

提问于
浏览
1421

注意:从ECMAScript版本3或5的角度提出了这个问题 . 在ECMAScript 6发布中引入新功能后,答案可能会过时 .

JavaScript中 var 关键字的功能到底是什么,有什么区别

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

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

你什么时候使用其中任何一个,为什么/它做什么?

18 回答

  • 0

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

  • 2

    如果你're in the global scope then there'没什么区别 . 阅读Kangax's答案进行解释

    如果你在函数中,那么 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
        }())
    }
    

    如果你没有做任务,那么你需要使用 var

    var x; // Declare x
    
  • 1273

    There's a difference .

    var x = 1 declares variable x 在当前范围内(也称为执行上下文) . 如果声明出现在函数中 - 声明了局部变量;如果它在全局范围内 - 声明了一个全局变量 .

    另一方面, x = 1 仅仅是 property 分配 . 它首先尝试针对作用域链解析 x . 如果它在该范围链中的任何位置找到它,它将执行赋值;如果找不到 x ,则只有 it creates x property on a global object (这是作用域链中的顶级对象) .

    现在,请注意它没有声明全局变量,它会创建一个全局属性 .

    两者之间的区别是微妙的,可能会让人感到困惑,除非你理解 variable declarations also create properties (仅在变量对象上)并且Javascript中的每个属性(好吧,ECMAScript)都有某些描述其属性的标志 - ReadOnly,DontEnum和DontDelete .

    由于变量声明使用DontDelete标志创建属性,因此 var x = 1x = 1 (在全局范围内执行时)之间的区别在于前一个 - 变量声明 - 创建DontDelete 'able property, and latter one doesn' t . 因此,可以从全局对象中删除通过此隐式赋值创建的属性,并且不能删除前一个 - 通过变量声明创建的属性 .

    但这当然只是理论,并且由于实现中的各种错误(例如来自IE的错误) .

    希望这一切都有道理:)


    [Update 2010/12/16]

    在ES5(ECMAScript 5;最近标准化,该语言的第5版)中,有一种所谓的"strict mode" - 一种选择加入语言模式,它略微改变了未声明的作业的行为 . 在严格模式下,对未声明标识符的分配是 ReferenceError . 这样做的理由是捕获意外分配,防止产生不希望的全局属性 . 一些较新的浏览器已经开始支持严格模式 . 例如,见my compat table .

  • 130

    说它是“ localglobal ”之间的区别并不完全准确 .

    将它视为“ localnearest ”之间的区别可能会更好 . 最近的肯定是全球性的,但情况并非总是如此 .

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

    当Javascript在浏览器中执行时,所有代码都被with语句包围,如下所示:

    with (window) {
        //Your code
    }
    

    更多信息with - MDN

    由于 var 在当前范围内声明了一个变量,因此声明 var inside window 并且根本不声明它之间没有区别 .

    当你没有直接进入窗户时,就会产生差异,例如:在函数内部或块内部 .

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

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

    编辑:在收到批评后,我想强调以下内容:

    • var 在当前范围内声明变量

    • 全球范围是 window

    • 不使用 var 在全局范围(窗口)中隐式声明 var

    • 使用 var 在全局范围(窗口)中声明变量与省略它相同 .

    • 使用 var is not the same thing 声明与窗口不同的作用域中的变量,因为声明不带 var 的变量

    • 始终明确声明 var ,因为这是一种很好的做法

  • 76

    您应该始终使用 var 关键字来声明变量 . 为什么?良好的编码实践本身就足够了,但是声明一个没有 var 关键字的变量意味着它在 global 范围内声明(像这样的变量称为"implied" global) . Douglas Crockford recommends never using implied globals,并根据Apple JavaScript Coding Guidelines

    在没有var关键字的情况下创建的任何变量都是在全局范围内创建的,并且在函数返回时不会被垃圾收集(因为它不会超出范围),从而导致内存泄漏的机会 .

    因此,简而言之,始终使用 var 关键字声明变量 .

  • 8

    这里的一个很好的例子,说明如何通过 var 来声明局部变量:

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

    i 在循环的每次迭代时都会重置,因为它没有在 for 循环中本地声明但是全局声明)最终导致无限循环

  • 1

    我想说在大多数情况下使用 var 会更好 .

    局部变量总是比全局范围内的变量快 .

    如果不使用 var 声明变量,则变量将位于全局范围内 .

    有关详细信息,您可以在Google中搜索“范围链JavaScript” .

  • 12

    另一个不同之处

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

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

    没有 var - 全局变量 .

    强烈建议 ALWAYS 使用 var 语句,因为在本地上下文中的init全局变量 - 是邪恶的 . 但是,如果你需要这个肮脏的技巧,你应该在页面开头写评论:

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

    不要使用var!

    var 是ES6之前声明变量的方式 . 我们现在在将来,你应该这样编码 .

    使用const和let

    const 应该用于95%的案例 . 它使得变量引用无法更改,因此数组,对象和DOM节点属性可以更改,并且可能应该是 const .

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

    两者都具有块级别范围,正如大多数其他语言所预期的那样 .

  • 0

    这是我为您编写的示例代码,用于理解此概念:

    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('
    '); document.write('
    '); document.write(foo); //prints 5 document.write(bar); //prints 100 document.write(fooba); //prints 3
  • 0

    在代码中,如果您在不使用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 */
    }
    
  • 706

    不使用“var”变量只能定义何时设置值 . 例如:

    my_var;
    

    无法在 global scopeany other scope 中工作 . 它应该具有如下 Value :

    my_var = "value";
    

    另一方面,你可以定义一个像vaiable;

    var my_var;
    

    它的值是 undefined (它的值不是 null 并且它有趣地不等于 null . ) .

  • 37

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

    如果您运行此代码:

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

    输出将显示为:false,false,true,true

    因为它将函数中的变量视为与其外部的变量分开,因此术语局部变量,这是因为我们在赋值中使用了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);
    

    输出为false,false,false,false

    这是因为它不是在局部范围或函数中创建新变量,而是简单地使用全局变量并将它们重新指定为false .

  • 0

    在使用或不使用 var 以及函数内部或外部声明变量时,我看到人们感到困惑 . 这是一个深入的示例,将引导您完成以下步骤:

    See the script below in action here at 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);
    

    结论无论是否使用var(如a,b)声明如果它们在函数外部获得它们的值,它们将保留它们的值,并且还保留通过脚本在各种函数内添加的任何其他值 . 如果变量在函数内部声明没有var(如c),它将像以前的规则一样,从现在起它将保留其在所有函数中的值 . 要么它在函数testVar1()中得到它的第一个值,它仍然保留该值并在函数testVar2()中获得附加值如果变量仅在函数内声明为var(如testVar1或testVar2中的d),则每次都将定义它 . 功能结束 . 所以它将是函数中的临时变量 .

  • 7

    您应该使用var关键字,除非您打算在浏览器中将变量附加到window对象 . Here's a link that explains scoping and difference between glocal scoping and local scoping with and wihtout var keyword.

    当变量在不使用var关键字的情况下定义时,它看起来像是一个简单的“赋值”操作 .

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

    你可能还想看hoisting in javascript

  • 5

    @Chris S给出了一个很好的例子,展示了 var 和没有 var 之间的实际差异(和危险) . 这是另一个,我发现这个特别危险,因为差异仅在异步环境中可见,所以它在测试期间很容易漏掉 .

    正如您所期望的那样,以下代码段输出 ["text"]

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

    以下代码段也是如此(注意在 array 之前缺少 let ):

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

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

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

    但对多个行为有不同的表现:

    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:

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

相关问题