1

由于这种奇怪的行为,我在我的网站中发现了一个错误。第二个函数警告“未定义”而不是“一”。

function test() {
    var myParam = "one"
    if (false) {
        var myParam = "two";
    }
    alert(myParam);
}
test(); // alert "one"


function testAjax() {
    var myParam = "one";
    $.ajax({
        url:    "http://url-to-get-error",
        error:  function(){
            if (false) {
                var myParam = "two";
            }
            alert(myParam);
        }
    });
}
testAjax(); // alert "undefined"

如果我在下面评论块,正确地提醒“一个”。有人知道为什么吗?

if (false) {
var myParam = "two";
}

请参阅http://jsfiddle.net/EaW8D/2/


更新

各位大侠,我知道怎么解决这个问题了,非常感谢!

但问题是为什么 js在一个从不运行的块中设置 undefinedif (false) ( )。

4

4 回答 4

5

有人知道为什么吗?

myParam您正在错误处理程序内部重新声明,在外部范围中隐藏具有相同名称的变量。变量声明被“提升”到函数的顶部,因此您的代码实际上与以下内容相同:

error:  function(){
    var myParam;  // <- declaration
    if (false) {
        myParam = "two"; // <-  initialization
    }
    alert(myParam);
}

并且由于该if块永远不会执行,myParam因此将是undefined(未初始化变量的默认值)。

这是一个简单的例子来证明这种行为。如果变量没有被提升,foo将成为一个全局变量(假设非严格模式)和一个属性window,但它不会:

(function() {
    if(false) {
        var foo = 'bar';
    }
    foo = 'baz';
    console.log(window.foo); // yields `undefined`
}());

要解决这个问题,只需删除var,以便myParam引用在外部范围中声明的变量,testAjax

error:  function(){
    if (false) {
        myParam = "two";
    }
    alert(myParam);
}
于 2012-07-18T18:39:42.937 回答
2

myParam因为你new var又在创造

function testAjax() {
    var myParam = "one";
    $.ajax({
        url:    "http://url-to-get-error",
        error:  function(){
            if (false) {
                myParam = "two";
            }
            alert(myParam);
        }
    }); 
}
testAjax(); // alert "undefined"​

http://jsfiddle.net/mKdhx/

于 2012-07-18T18:29:06.407 回答
2

表单的所有变量声明var myParam都被提升到函数范围的顶部。即使它们在不可访问的块中或在函数的末尾,在任何地方var都有声明的函数将把该变量名的所有实例视为本地的。

考虑这个处理程序:

    error:  function(){
        alert(myParam);
        var myParam;
    }

它也会引起undefined警报,因为var myParam底部的意思是,“将此声明之前和之后的所有实例myParam都视为此函数中的局部变量。 ”在这种情况下适用的相同提升适用于您的不可访问逻辑-块案例。

于 2012-07-18T18:42:44.903 回答
-1

在第二种情况下,您的 myParam=one 和 myParam=two 位于不同的块中 - 此外,就变量可见性而言,ajax 错误的回调不是“低于”testAjax - 它是异步的。您将需要 myParam 在全局范围内

于 2012-07-18T18:30:42.523 回答