Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:函数中的变量重新声明导致未定义_Javascript_Scope_Hoisting - Fatal编程技术网

Javascript:函数中的变量重新声明导致未定义

Javascript:函数中的变量重新声明导致未定义,javascript,scope,hoisting,Javascript,Scope,Hoisting,为什么console.log(foo)会生成undefined而不是中的'bar'- var foo = 'bar'; (function() { console.log(foo); if(foo === 'baz') { var foo = 'qux'; } })(); -但是如果var foo替换为foo,会产生'bar'?我知道重新声明变量是不好的做法,但无论如何都不会对var foo='qux'进行计算,即使是这样,它也不应该做任何事情,对吗 J

为什么
console.log(foo)
会生成
undefined
而不是中的
'bar'
-

var foo = 'bar';
(function() {
    console.log(foo);
    if(foo === 'baz') {
        var foo = 'qux';
    }
})();
-但是如果
var foo
替换为
foo
,会产生
'bar'
?我知道重新声明变量是不好的做法,但无论如何都不会对
var foo='qux'
进行计算,即使是这样,它也不应该做任何事情,对吗

Javascript“提升”变量声明,这意味着代码中稍后出现的变量声明被“提升”到其包含范围的顶部。这意味着:

(function() {
    console.log(foo);
    if(foo === 'baz') {
        var foo = 'qux'
    }
});
变成:

(function() {
    var foo;
    console.log(foo);
    if(foo === 'baz') {
         foo = 'qux'
    }
}); 
即使
foo
的重新分配/重新声明从未显式运行。对提升的总结远远不够充分

然而,乍一看,我们的示例看起来像一个例子。诀窍在于,由于函数从其包含作用域(在本例中为全局作用域)继承了自己的作用域,因此声明任何变量(即使它存在于继承的作用域中)都保证在赋值之前
未定义


我最初想提出这个问题,因为我认为这是
setTimeout
cleartimout
的错误,像这样的代码不断抛出
无法设置未定义的属性“className”:

var timer;
document.getElementById('ele').addEventListener('mousewheel', function() {
    var that = this;
    clearTimeout(timer);
    timer = setTimeout(function() {
        that.className = 'foo';
        if(false) { //this condition shouldn't have ever been true in my test cases
            var that = document.getElementById('otherEle');
            setTimeout(function() { /* Things to do with otherEle in 1s */ }, 1000);
        }
    }, 200);
}, false);

后来我发现,重新声明的
变量是罪魁祸首,经过一些研究,我得出结论,吊装和功能范围界定是罪魁祸首。不过,我不知道我对范围界定的解释是否完全准确,我希望得到反馈。

你的解释是正确的。一些程序员在其作用域的顶部声明所有变量,以帮助避免类似这样的问题(或者在您的例子中,
)。