在函数中,在变量之前使用/不使用var会发生什么?

时间:2013-01-07 03:31:22

标签: javascript

这是我的代码

var a = this.innerHTML;

var b = 'blababibbaib';

if(a !== b)
    {
        c = a;
        return this.innerHTML = b;
    }
else
    {
        return this.innerHTML = c;
    }

和var

var a = this.innerHTML;

var b = 'blababibbaib';

if(a !== b)
    {
       var c = a; // here with the var it makes c undefined :-(
        return this.innerHTML = b;
    }
else
    {
        return this.innerHTML = c;
    }

我这样做的原因是因为我想要一个onclick事件的函数,它可以在原始事件和var b之间来回切换。只是为了好玩。

但我不明白为什么当你在c变量前面添加var时,一旦你点击它就会使它变得不确定。有人会照亮我吗?

我猜测它在函数????

中使用时与变量范围有关

提前致谢: - )

编辑:

好的,我这样做是为了用var声明它,但我仍然不确定为什么。

在函数外部,我在声明之前添加了if检查c

if(!c) var c = '';

但就像我说的那样,我仍然想听听最新情况以及为什么谢谢: - )

编辑2:谢谢大家,现在阅读有关提升的内容。

我觉得很困惑,甚至你也不需要检查c。想到可能很重要......哦,好吧。再次感谢

6 个答案:

答案 0 :(得分:4)

第二个例子中发生的事情等同于:

var a = this.innerHTML;

var b = 'blababibbaib';

var c; // all "var" are hoisted to the top of a function body

if(a !== b)
    {
        c = a;
        return this.innerHTML = b;
    }
else
    {
        // local c variable not set yet - undefined
        return this.innerHTML = c;
    }

显然c在此处未定义,因为仅在未设置时才输出。我怀疑你真正想要的是:

var a; //This persists after the function is invoked

myelement.onclick = function () {
    if (!a) { // Only save the value if it isn't already set
        a = this.innerHTML;
    }
    var b = 'blababibbaib';

    if (this.innerHTML == b) {
        return this.innerHTML = a;
    } else {
        return this.innerHTML = b;
    }
};

你可以看到它here

就第一个片段而言,它起作用是因为c的值不是函数的本地值,并且在调用后仍然存在。当您在函数体中指定或引用变量而未使用var关键字声明它时,它会自动引用具有相同名称的window属性。请考虑以下事项:

window.c = "Hello, world.";

//Note how there is no local c variable;
//the c here refers to window.c
function test1(){
    alert(c);
}

//There is a c variable local to the 
//function, so the value alerted is not the value of window.c
function test2(){
    var c;
    alert(c);
}

test1(); // alerts "Hello, world."
test2(); // alerts "undefined"

在第一个代码段中,只要HTML不是window.c,您就会将this.innerHTML的值更改为"blababibbaib"。当值 "blababibbaib"时,您依靠window.c重置元素的innerHTML

您可能希望阅读JS中的hoisting以及implicit globals

答案 1 :(得分:1)

没有var前缀c成为全局变量,并且在所有范围内都可用。

JavaScript只有函数作用域,因此使用var将变量作用于最近的函数上下文(如果未在函数内声明,则为全局作用域)。

答案 2 :(得分:1)

这可能是因为你的变量c只存在于if语句中,所以你需要这样做:

var a = this.innerHTML;

var b = 'blababibbaib';
var c;
if(a !== b)
    {
       var c = a; // here with the var it makes c undefined :-(
        return this.innerHTML = b;
    }
else
    {
        return this.innerHTML = c;
    }

使用第一个代码,因为您没有使用var c,这会使c成为全局变量。

答案 3 :(得分:0)

遵循你的逻辑,c只会在if中设置,而不是在else中。因此,如果c是一个存在于函数外部的全局变量,它可以在调用之间保持“状态”。如果你在里面用var声明它,那么它就会变成每次调用的本地。

答案 4 :(得分:0)

如果不为特定范围内的变量分配新内存,则默认使用与父范围链相匹配的变量。

使用'var'关键字触发当前作用域中的内存分配,否则将该值指定为window的成员,这对于对函数的调用是持久的。

答案 5 :(得分:0)

这有点令人困惑,但在你知道的时候应该很容易记住。在定义变量时省略var关键字时,变量将附加到全局范围。这通常是编写良好的程序中的一个不受欢迎的程序,因为你有漂浮的变量应该在范围到期时被处理掉。

在您的情况下,当您在var c = a语句中添加if时,即使javascript自动hoists变量到函数范围 - 即变量名称将存在 - 但在遇到var c = a代码行之前,它不会为其赋值。默认情况下,未分配值的任何变量都将获得undefined状态。

当您省略var时,c被提升为全局范围,只要您在页面上,全局状态就会保留c的值。因此,回到else条款,您将获得有效但旧的c值。

根据经验,没有var定义的变量不是一个好习惯,你应该定义在函数开头附近使用的所有变量,以避免与提升相混淆或者尤其如果你来自C / C ++ / Java背景。