关于javascript:使用”var”声明变量是可选的吗?

Is using 'var' to declare variables optional?

本问题已经有最佳答案,请猛点这里访问。

"var"是可选的吗?

1
myObj = 1;

等同于?

1
var myObj = 1;

我发现它们都能通过我的测试工作,我假设var是可选的。对吗?


他们的意思不同。如果使用var,则变量将在您所处的范围(例如函数)内声明。如果不使用var,变量会在作用域的各个层中冒泡,直到它遇到一个给定名称的变量或全局对象(窗口,如果在浏览器中这样做的话),然后在那里附加。然后它非常类似于一个全局变量。但是,它仍然可以用delete删除(很可能是被其他人的代码删除,这些代码也没有使用var)。如果在全局范围内使用var,则变量是真正的全局变量,不能删除。

在我看来,这是JavaScript最危险的问题之一,应该被弃用,或者至少对警告提出警告。原因是,很容易忘记var,并意外地将一个公共变量名绑定到全局对象。这会产生奇怪且难以调试的行为。


这是JavaScript的一个复杂部分,也是它的核心功能之一。用var声明的变量"开始其生命"就在您声明的地方。如果不考虑var,就好像是在谈论一个以前使用过的变量。

1
2
var foo = 'first time use';
foo = 'second time use';

关于范围,变量自动变为全局是不正确的。相反,javascript将遍历作用域链,以查看您以前是否使用过该变量。如果它找到一个以前使用过的同名变量的实例,那么它将使用这个实例以及在其中声明的任何范围。如果它在任何地方都没有遇到这个变量,它最终会击中全局对象(浏览器中的window),并将该变量附加到它上面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var foo ="I'm global";
var bar ="So am I";

function () {
    var foo ="I'm local, the previous 'foo' didn't notice a thing";
    var baz ="I'm local, too";

    function () {
        var foo ="I'm even more local, all three 'foos' have different values";
        baz ="I just changed 'baz' one scope higher, but it's still not global";
        bar ="I just changed the global 'bar' variable";
        xyz ="I just created a new global variable";
    }
}

这种行为在与嵌套函数和回调一起使用时非常强大。了解functions是什么以及范围如何工作是JavaScript中最重要的事情。


不,它们不是等价的。

对于myObj = 1;,您使用的是全局变量。

后一个声明创建了一个您正在使用的作用域的局部变量。

请尝试以下代码以了解差异:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
external = 5;
function firsttry() {
  var external = 6;
  alert("first Try:" + external);
}

function secondtry() {
  external = 7;
  alert("second Try:" + external);
}

alert(external); // Prints 5
firsttry(); // Prints 6
alert(external); // Prints 5
secondtry(); // Prints 7
alert(external); // Prints 7

第二个函数改变了全局变量"外部"的值,但第一个函数没有。


不仅仅是本地和全球。使用var创建的全局变量与不使用var创建的全局变量不同。考虑一下:

1
2
3
var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object

根据目前的答案,这些全局变量,foobarbaz都是等价的。事实并非如此。使用var生成的全局变量被(正确地)分配给内部[[DontDelete]]属性,这样它们就不能被删除。

1
2
3
4
5
6
7
delete foo; // false
delete bar; // true
delete baz; // true

foo; // 1
bar; // ReferenceError
baz; // ReferenceError

这就是为什么您应该始终使用var,即使对于全局变量也是如此。


var是可选的。var将变量放在局部范围内。如果定义的变量不带var,则该变量在全局范围内且不可删除。

编辑

我认为不可删除的部分在某个时间点上是真实的,在某个环境中。我一定是梦到了。


关于这个问题有太多的困惑,现有的答案没有一个能清楚、直接地涵盖一切。下面是一些内嵌注释的示例。

1
2
3
4
5
6
7
8
//this is a declaration
var foo;

//this is an assignment
bar = 3;

//this is a declaration and an assignment
var dual = 5;

声明设置DontDelete标志。任务没有。

声明将该变量绑定到当前范围。

已分配但未声明的变量将查找要附加到的范围。这意味着它将遍历作用域的食物链,直到找到同名的变量为止。如果找不到,它将附加到顶级作用域(通常称为全局作用域)。

1
2
3
4
5
6
7
8
9
10
11
12
13
function example(){
  //is a member of the scope defined by the function example
  var foo;

  //this function is also part of the scope of the function example
  var bar = function(){
     foo = 12; // traverses scope and assigns example.foo to 12
  }
}

function something_different(){
     foo = 15; // traverses scope and assigns global.foo to 15
}

为了非常清楚地描述正在发生的事情,对delete函数的分析广泛地涉及变量实例化和赋值。


看看这个小提琴:http://jsfiddle.net/gwr6z/2/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function doMe(){

a ="123"; // will be global
var b ="321"; // local to doMe
alert("a:"+a+"  --  b:"+b);

b ="something else"; // still local (not global)
alert("a:"+a+"  --  b:"+b);

};


doMe()
alert("a:"+a+"  --  b:"+b); // `b` will not be defined, check console.log


它们不一样。

未声明的变量(不带var)被视为全局对象的属性。(通常是window对象,除非你在with块中)

var声明的变量是正常的局部变量,在声明它们的函数之外不可见。(注意,javascript没有块范围)


javascript中的var关键字是有目的的。

如果声明一个没有var关键字的变量,如下所示:

1
myVar = 100;

它成为一个全局变量,可以从脚本的任何部分访问。如果您不是故意这样做或者不知道,如果您在JavaScript的另一个地方重新使用变量名,可能会导致您的痛苦。

如果用var关键字声明变量,如下所示:

1
var myVar = 100;

它是作用域的局部(]—大括号、函数、文件,具体取决于放置位置)。

这是一种更安全的处理变量的方法。因此,除非您是故意这样做的,否则尝试使用var关键字声明变量,而不是不使用var关键字。


var不允许程序员声明变量,因为javascript没有变量。javascript有对象。var显式向未定义的对象声明名称。赋值将名称作为句柄分配给已给定值的对象。

使用var可以告诉javascript解释器两件事:

  • 不要对名称使用委托反向遍历查找值,而是使用此值
  • 不删除名称
  • var的省略告诉javascript解释器使用第一个找到的同名对象的前一个实例。

    var作为关键字源于语言设计者的错误决策,这与javascript作为名称源于错误决策的方式非常相似。

    ps.学习上面的代码示例。


    考虑一下今天StackOverflow上提出的这个问题:

    简单的javascript问题

    一个好的测试和一个实际的例子就是在上面的场景中发生的事情…开发人员在他的一个变量中使用了javascript函数的名称。

    代码有什么问题?该代码只在用户第一次单击按钮时工作。

    解决办法是什么?在变量名之前添加var关键字。


    不,它不是"必需的",但如果您不这样做,它也可能会导致严重的问题。不使用var定义变量会将该变量放在它所在的代码部分的范围内。如果没有,则它不包含在该作用域中,并且可以覆盖先前定义的变量,这些变量的名称与您所在函数作用域之外的名称相同。


    除了范围之外的所有内容,它们可以用不同的方式。

    1
    2
    3
    4
    console.out(var myObj=1);
    //SyntaxError: Unexpected token var
    console.out(myObj=1);
    //1

    陈述与表达


    我刚从一位同事推荐的论坛上找到答案。如果在函数外部声明一个变量,它总是全局的。无论您是否使用var关键字。但是,如果在函数中声明变量,它有很大的区别。在函数内部,如果使用var关键字声明变量,它将是本地的,但是如果不使用var关键字声明变量,它将是全局的。它可以覆盖以前声明的变量。-更多信息,请访问:http://forum.webdeveloperszone.com/question/what is the difference between using var keyword or not using var during variable declaration/sthash.xnnlrwc3.dpuf