【发布时间】:2014-09-23 12:50:25
【问题描述】:
这是我不太了解的 Javascript 作用域和全局变量与局部变量的一些特定微妙之处 - 并且可能导致 if 条件中的代码出现令人惊讶的情况,从而影响 if 条件是否为评估:代码受到尚未“发生”的代码的影响。
我已将其缩减为 JSBIN DEMO 比较两个几乎相同的代码块。
首先,一切都按预期进行。我们定义了一个全局变量,然后在一个范围内,我们检查它是否被定义,看看它是,然后继续:
someVar = function(){}; // or, window.someVar =...
(function(){
console.log("before", someVar, typeof someVar);
if(typeof someVar == 'undefined'){
someVar = true;
}
console.log("after", someVar, typeof someVar);
})();
控制台显示变量是一个函数,并且 if 被跳过,正如预期的那样。
但是,如果我们将if 中的行更改为使用var,它会更改变量之前 中更改的状态代码已到达。
在这个变体中,除了将var 添加到if 内的行之外,没有任何变化,变量之前两行切换到undefined,现在评估if:
someVar = function(){}; // or, window.someVar =...
(function(){
console.log("before", someVar, typeof someVar);
if(typeof someVar == 'undefined'){
var someVar = true; // <<<<< the only change is adding var here
}
console.log("after", someVar, typeof someVar);
})();
控制台显示变量现在是 undefined 在 if 之前,并由现在正在评估的 if 切换。
编辑:即使var 声明永远不会发生,也会发生同样的事情:
neverVar = function(){}; // or, window.neverVar ...
(function(){
console.log("never-before", neverVar, typeof neverVar);
if(false){ // never do this
var neverVar = "changed";
}
console.log("never-after", neverVar, typeof neverVar);
})();
我认为 JS 代码不可能在到达之前影响代码的执行 - 但显然 var 稍后在代码中的存在以某种方式阻止了整个范围的全局查看。
从 jsbin 的警告来看,它是否被认为超出范围取决于范围内是否存在 var 语句,即使该 var 语句尚未被评估或预计不会被评估评估。
谁能解释一下?
(出于好奇,还有其他的 Javascript 执行示例会受到未评估代码的影响吗?)
【问题讨论】:
-
除了给出的答案,别忘了Javascript默认作用域不是块作用域,是函数作用域。
标签: javascript if-statement scope global