当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《var关键字的目的是什么?我何时应该使用它(或省略它)?》经验,为你挑选了11个好方法。

如果你在全球范围内,则没有太大区别.阅读Kangax的答案进行解释

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

嗯,实际上是的,有区别:)这个差异是否重要是另一个问题.请进一步查看我的答案:http://stackoverflow.com/questions/1470488/difference-between-using-var-and-not-using-var-in-javascript#answer-1471738 (65认同)

"没有太大区别"=="没有差异"? (31认同)

就像用铁轨枪射击自己一样......忘记在一个变量之前加上'var',最后修改范围链中某个变量**尝试说服Java/C/Python等.开发人员认为JavaScript是值得的.哈!相比之下,C/C++陷阱看起来很不错.想象一下,必须调试JavaScript ......当然,有些人会这样做.用JavaScript编写的代码很多(而不是简单的代码,请注意)... (18认同)

_如果你在全球范围内,则没有区别._ >>有一个区别在下面的答案中解释 (6认同)

我认为这可能是亚历克斯的观点,这就是为什么他用"等于"运算符写它的原因! (4认同)

@Alex 0 == false,所以是"没有太大区别"=="没有差异"然而"没有太大区别"!=="没有区别" (3认同)


kangax.. 733

有区别.

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

x = 1另一方面,仅仅是财产分配.它首先尝试解决x范围链.如果它在该范围链中的任何位置找到它,它将执行赋值; 如果它没有找到x,那么x才会在全局对象(它是作用域链中的顶级对象)创建属性.

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

两者之间的区别是微妙的,可能会令人困惑,除非您了解变量声明也创建属性(仅在变量对象上),并且Javascript中的每个属性(即,ECMAScript)都有某些描述其属性的标志 - ReadOnly,DontEnum和DontDelete.

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

但这当然只是理论,实际上由于实现中的各种错误(例如来自IE的错误),两者之间存在更多差异.

希望这一切都有道理:)


[更新2010/12/16]

在ES5(ECMAScript 5;最近标准化,第5版语言)中,有一种所谓的"严格模式" - 一种选择加入语言模式,它稍微改变了未声明的作业的行为.在严格模式下,对未声明标识符的赋值是ReferenceError.其基本原理是捕获意外分配,防止产生不希望的全局属性.一些较新的浏览器已经开始支持严格模式.例如,请参阅我的compat表.



1> Greg..:

如果你在全球范围内,则没有太大区别.阅读Kangax的答案进行解释

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


嗯,实际上是的,有区别:)这个差异是否重要是另一个问题.请进一步查看我的答案:http://stackoverflow.com/questions/1470488/difference-between-using-var-and-not-using-var-in-javascript#answer-1471738
"没有太大区别"=="没有差异"?
就像用铁轨枪射击自己一样......忘记在一个变量之前加上'var',最后修改范围链中某个变量**尝试说服Java/C/Python等.开发人员认为JavaScript是值得的.哈!相比之下,C/C++陷阱看起来很不错.想象一下,必须调试JavaScript ......当然,有些人会这样做.用JavaScript编写的代码很多(而不是简单的代码,请注意)...
_如果你在全球范围内,则没有区别._ >>有一个区别在下面的答案中解释
我认为这可能是亚历克斯的观点,这就是为什么他用"等于"运算符写它的原因!
@Alex 0 == false,所以是"没有太大区别"=="没有差异"然而"没有太大区别"!=="没有区别"

2> kangax..:

有区别.

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

x = 1另一方面,仅仅是财产分配.它首先尝试解决x范围链.如果它在该范围链中的任何位置找到它,它将执行赋值; 如果它没有找到x,那么x才会在全局对象(它是作用域链中的顶级对象)创建属性.

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

两者之间的区别是微妙的,可能会令人困惑,除非您了解变量声明也创建属性(仅在变量对象上),并且Javascript中的每个属性(即,ECMAScript)都有某些描述其属性的标志 - ReadOnly,DontEnum和DontDelete.

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

但这当然只是理论,实际上由于实现中的各种错误(例如来自IE的错误),两者之间存在更多差异.

希望这一切都有道理:)


[更新2010/12/16]

在ES5(ECMAScript 5;最近标准化,第5版语言)中,有一种所谓的"严格模式" - 一种选择加入语言模式,它稍微改变了未声明的作业的行为.在严格模式下,对未声明标识符的赋值是ReferenceError.其基本原理是捕获意外分配,防止产生不希望的全局属性.一些较新的浏览器已经开始支持严格模式.例如,请参阅我的compat表.


@Mageek他可能正在考虑可删除的eval声明的变量.我曾写过一篇[博客文章](http://perfectionkills.com/understanding-delete/).

3> Jonathan Lon..:

说它是" 本地全球 " 之间的区别并不完全准确.

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

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


是不是最近的范围`outer`你定义`var global = false;`?

4> kentaromiura..:

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

with (window) {
    //Your code
}

有关更多信息with- MDN

由于在当前作用域中var声明了一个变量,因此在声明内部窗口和根本不声明它之间没有区别.var

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

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

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

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

var声明当前范围中的变量

全球范围是 window

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

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

声明在使用窗口不同的范围的变量var 是不一样的东西作为声明的变量,而不var

始终var明确声明,因为这是一个好习惯


我只是用它的名字来调用它,你想把它称为"全局范围",没关系,但是客户端,按照惯例,是窗口对象,这是范围链的最后一个元素,为什么你可以调用每个函数和窗口中的每个对象都没有写"窗口".
+1这是一个非常好的解释 - 我之前没有听到过var/no var问题框架(没有双关语).
@EvanCarroll这个答案在技术上也是不正确的,因为省略var不会声明任何变量,而是在全局对象上创建一个可删除的属性,除了ES5"use strict"模式,大多数答案显然是不正确的,也让我没有甚至在这个答案中都考虑过,因为在问题发生时没有提到javascript版本(昨天添加),这意味着参考标准(当时)是ECMA 262第3版.

5> Steve Harris..:

您应该始终使用var关键字来声明变量.为什么?良好的编码实践本身就足够了,但是在没有var关键字的情况下声明变量意味着它在全局范围内声明(像这样的变量称为"隐含"全局).Douglas Crockford 建议不要使用隐含的全局变量,并根据Apple JavaScript编码指南:

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

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


"良好的编码实践"本身不应该是充分理由.这相当于"互联网上的一些人说这是我的代码看起来的样子".这比"老师说的"更有效,除非至少模糊地理解规则背后的原因.
@ChrisS:不,"良好的编码实践"本身并不是理由.*原因*被认为是好的做法才是最重要的.除非那些作者告诉你他们为什么推荐它,否则他们的推荐应该没有任何重量.如果您不同意原因,那么您可以自由地认为这是不好的建议.如果你在没有问过为什么的情况下遵循它,那就是货运文化的起源.

6> Chris S..:

这里有一个很好的例子,说明如何通过以下方式来解决局部变量var:


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


我很好奇,为什么你把我作为一个参数传递给两个()?(for循环内部)是多余的?

7> Billy..:

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

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

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

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



8> Gibolt..:
不要用var!

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

使用constlet

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

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

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


将所有'var'替换为'const'(全部替换).您将很快发现重新分配的变量在哪里.如果你有太多它们,你可能反模式编码:大多数可重新分配的变量可以嵌入到闭包中或作为对象属性.如果你有几个:对他们使用'let'.最后,如果某些变量完全没有使用'var',它们将保持未声明,并且仍然存在于全局空间中,请注意.关于@Gibolt评论'在for循环中',也建议在"95%的情况下"避免这样的循环;-):数组方法很棒.

9> Anatoliy..:

没有var- 全局变量.

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

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



10> 小智..:

另一个区别,例如

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

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


@Lucek因为`var a`被提升到作用域的顶部并设置为null,它声明但不初始化变量,然后在赋值中你有一个未定义的null变量的引用,该变量的计算结果为false,并将赋值设置为`[]`.在后者中,你有一个属性`a`的属性`a`的赋值.您可以分配给不存在的属性 - 在赋值时创建它,但是如果没有引用"ReferenceError",则无法读取不存在的属性.

11> kevinji..:

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

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有