使用'var'来声明变量是可选的吗?

Ray*_* Lu 349 javascript

"var"是可选的吗?

myObj = 1;
Run Code Online (Sandbox Code Playgroud)

与...一样 ?

var myObj = 1;
Run Code Online (Sandbox Code Playgroud)

我发现它们都是我的测试,我认为var是可选的.是对的吗?

Ste*_*ini 566

他们的意思不同.如果使用var变量,则在您所在的范围内声明(例如函数).如果你不使用var,变量会通过范围层向上冒泡,直到它遇到给定名称或全局对象(窗口,如果你在浏览器中执行它)的变量,然后它会附加.它全局变量非常相似.但是,它仍然可以删除delete(很可能是其他人的代码也未能使用var).如果var在全局范围内使用,则该变量是真正的全局变量,无法删除.

在我看来,这是javascript最危险的问题之一,应该被弃用,或至少引发警告警告.原因是,很容易忘记var并且偶然发生绑定到全局对象的公共变量名称.这会产生奇怪且难以调试的行为.

  • 实际上没有,在不使用`var`的情况下分配变量不会使*global*.它会导致JS遍历作用域链,如果之前没有使用该变量,最终会终止于全局对象.如果变量*在全局之前使用`var`声明*,那就是将要使用的范围.它也是JS如何工作以及使其真正强大的一部分,因此我不会将其描述为"陷阱". (45认同)
  • @deceze:遍历范围链是一件好事,但如果找不到任何东西,将其添加到全局范围是一个陷阱. (32认同)
  • @codemeit:javascript充满了这样的陷阱,但总而言之,它是一种美丽而愉快的语言.不要讨厌它.只要知道陷阱并将它们从代码中删除. (14认同)
  • 从ECMAScript 5严格模式中删除自动全局变量,这基本上是隐式弃用.如果在非严格模式下忘记`var`,希望实现会发出警告. (11认同)

dec*_*eze 120

这是Javascript的棘手部分之一,也是其核心功能之一.var在声明它的地方声明的变量"从它的生命开始".如果你遗漏了var,那就像你在谈论你以前用过的变量一样.

var foo = 'first time use';
foo = 'second time use';
Run Code Online (Sandbox Code Playgroud)

关于范围,变量自动变为全局是正确的.相反,Javascript将遍历范围链以查看您之前是否使用过该变量.如果它找到之前使用的同名变量的实例,它将使用它以及声明它的任何范围.如果它在任何地方都没有遇到变量,它最终将命中全局对象(window在浏览器中)并将变量附加到它.

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

与嵌套函数和回调一起使用时,此行为非常强大.了解functionsJavascript中最重要的是什么以及范围如何工作.

  • 这确实是最好的答案,因为了解范围链的实际行为是理解Javascript功能如何工作的关键 - 即使您不喜欢以函数式编写代码,也很高兴知道考虑了多少常用的库*做*使用功能风格. (16认同)

Ein*_*eki 79

不,他们不等同.

随着myObj = 1;您使用全局变量.

后一个声明为您正在使用的范围创建一个本地变量.

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

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
Run Code Online (Sandbox Code Playgroud)

第二个函数改变全局变量"external"的值,但第一个函数不改变.

  • 小心说"你正在使用全局变量"."myObj = 1;" 指外部范围中的变量,可能不是全局变量.但是,您的示例确实引用(并可能隐式声明)全局范围中的变量. (5认同)

bch*_*rry 21

除了本地和全球之外,还有更多内容.创建的全局变量与var不创建的变量不同.考虑一下:

var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object
Run Code Online (Sandbox Code Playgroud)

根据答案,到目前为止,这些全局变量,foo,bar,和baz都是等效的.这是不是这种情况.使用的全局变量var(正确)分配了内部[[DontDelete]]属性,因此无法删除它们.

delete foo; // false
delete bar; // true
delete baz; // true

foo; // 1
bar; // ReferenceError
baz; // ReferenceError
Run Code Online (Sandbox Code Playgroud)

这就是为什么你应该总是使用var,即使是全局变量.


kzh*_*kzh 14

var是可选的.var将变量放在局部范围内.如果没有定义变量var,则它在全局范围内且不可删除.

编辑

我认为不可删除的部分在某个环境中的某个时间点是正确的.我一定是梦到了.

  • 简短,但不正确.如果它是如你所说的那样"定义"没有var,你**可以**删除它.但是不使用var并不总是声明一个新变量,它可以引用外部作用域中的一个. (3认同)

Ste*_*tad 14

围绕这个主题存在很多混乱,现有的答案都没有清楚直接地涵盖所有内容.以下是一些内联注释的示例.

//this is a declaration
var foo;

//this is an assignment
bar = 3;

//this is a declaration and an assignment
var dual = 5;
Run Code Online (Sandbox Code Playgroud)

声明设置DontDelete标志.作业没有.

声明将该变量与当前范围联系起来.

已分配但未声明的变量将查找要将其自身附加到的范围.这意味着它将遍历范围的食物链,直到找到具有相同名称的变量.如果没有找到,它将附加到顶级范围(通常称为全局).

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
}
Run Code Online (Sandbox Code Playgroud)

为了清楚地描述正在发生的事情,对delete函数的这种分析涵盖了变量实例化和广泛分配.


Mil*_*Man 9

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

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
Run Code Online (Sandbox Code Playgroud)


SLa*_*aks 8

他们不一样.

未声明的变量(不var)被视为全局对象的属性.(通常是window对象,除非你在一个with街区)

声明的变量var是普通的局部变量,并且在它们声明的函数之外是不可见的.(注意,Javascript没有块范围)


Cyr*_*pta 6

Javascript中的var关键字是出于某种目的.

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

myVar = 100;
Run Code Online (Sandbox Code Playgroud)

它成为一个全局变量,可以从脚本的任何部分访问.如果您没有故意这样做或者没有意识到这一点,那么如果您在javascript中的其他位置重复使用变量名称,则可能会让您感到痛苦.

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

var myVar = 100;
Run Code Online (Sandbox Code Playgroud)

它是范围({] - 大括号,函数,文件的本地,具体取决于您放置它的位置).

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