【问题标题】:Javascript: variable redeclaration in functions causing undefined [duplicate]Javascript:函数中的变量重新声明导致未定义[重复]
【发布时间】:2015-07-12 02:58:44
【问题描述】:

为什么console.log(foo) 产生undefined 而不是'bar' in —

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

——但如果 var foo 被替换为 foo,则生成 'bar'?我知道重新声明变量是不好的做法,但是无论如何都不会对 var foo = 'qux' 进行评估,即使是这样,它也不应该做任何事情,对吧?

JSFiddle

【问题讨论】:

标签: javascript scope hoisting


【解决方案1】:

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

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

变成:

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

即使foo 的重新分配/“重新声明”从未显式运行。 Adequately Good 对提升的总结远远不够。

但是,乍一看,我们的示例看起来像this question 的情况。诀窍是,因为函数从它们的包含范围(在本例中为全局范围)有自己的范围继承,所以声明任何变量,即使它存在于继承的范围中,也保证是undefined 分配前。


我最初想提出这个问题,因为我认为像这样的代码不断抛出Cannot set property 'className' of undefinedsetTimeoutclearTimeout的错:

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);

我后来发现 var that 重新声明是罪魁祸首,经过一些研究,我得出结论认为提升和函数作用域是罪魁祸首。不过,我不知道我对范围界定的解释是否完全准确,希望得到反馈。

【讨论】:

  • 你的解释是正确的。一些程序员在其作用域的顶部声明所有变量,以帮助避免这样的问题(或者在你的情况下,that)。
猜你喜欢
  • 2018-02-04
  • 2019-09-29
  • 2016-06-16
  • 2013-04-28
  • 2013-01-23
  • 1970-01-01
  • 2011-02-07
  • 2022-08-17
  • 2022-01-03
相关资源
最近更新 更多