为什么console.log(foo)
在< - p>中产生undefined
而不是'bar'
var foo = 'bar';
(function() {
console.log(foo);
if(foo === 'baz') {
var foo = 'qux';
}
})();
- 如果'bar'
替换为var foo
,则生成foo
?我知道重新声明变量是不好的做法,但var foo = 'qux'
永远不会被评估,即使它是,它仍然不应该做任何事情,对吧?
答案 0 :(得分:1)
Javascript&#34; hoists&#34;变量声明,意味着稍后在代码中出现的变量声明是&#34;悬挂&#34;到他们包含范围的顶部。这意味着:
(function() {
console.log(foo);
if(foo === 'baz') {
var foo = 'qux'
}
});
变为:
(function() {
var foo;
console.log(foo);
if(foo === 'baz') {
foo = 'qux'
}
});
即使重新分配/&#34;重新声明&#34; foo
永远不会明确地运行。 Adequately Good总结起来远远超过了充分。
但是,乍一看,我们的示例看起来像是this question的情况。诀窍在于,因为函数具有自己的范围从其包含的范围继承(在本例中是全局范围),所以声明任何变量,即使它存在于继承范围内,也可以保证分配前undefined
。
我最初想提出这个问题,因为我认为这是setTimeout
和clearTimeout
的错误,这样的代码经常抛出Cannot set property 'className' of undefined
:
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
重新声明是罪魁祸首,经过一些研究后得出的结论是吊装和功能范围是罪魁祸首。不过,我不知道我对范围界定的解释是否完全准确,并且会很感激反馈。