【问题标题】:Javascript Variable ScopeJavascript 变量范围
【发布时间】:2011-07-07 06:17:49
【问题描述】:

我在加载时未定义 javascript 全局变量(称为 TimeStamp)时遇到问题……至少我认为这是问题所在。

我从这个开始,定义时间戳。

        $(document).ready(function(){
        // AddTest();
        var TimeStamp = null;
        waitForMsg();
    });

...waitForMsg 然后使用 TimeStamp 运行并在成功完成 ajax 调用时对其进行更新。至少是这样的想法,但目前没有任何运行,因为“未定义时间戳”......即使我之前定义了它! (呃)。

如果我在 waitForMsg 中重新定义时间戳,它只会被重置,而不是使用来自成功的 ajax 函数的更新值。

    function waitForMsg(){


    $.ajax({
        type: "POST",
        url: "backend.php",
        async: true,
        cache: false,
        timeout:50000, /* Timeout in ms */
        data: "TimeStamp=" + TimeStamp,
        success: function(data){

            var json = eval('(' + data + ')');

            $('#TextHistory :last-child').after('<p>' + json['msg'] + '</p>');


            TimeStamp = json['timestamp'];


            setTimeout(
                'waitForMsg()', /* Request next message */
                1000            /* ..after 1 seconds */
            );
        },
        error: function(XMLHttpRequest, textStatus, errorThrown){

            $('#TextHistory :last-child').after('<p>' + errorThrown + '</p>');

            setTimeout(
                'waitForMsg()', /* Try again after.. */
                "15000");       /* milliseconds (15seconds) */
        },
    });
};

非常感谢任何帮助。

丹。

【问题讨论】:

    标签: javascript variables jquery scope


    【解决方案1】:

    改变

    $(document).ready(function(){
        // AddTest();
        var TimeStamp = null;
        waitForMsg();
    });
    

    var TimeStamp = null;
    $(document).ready(function(){
        // AddTest();
        waitForMsg();
    });
    

    这样,它将存在于全局范围内,而不仅仅是在就绪函数的范围内。

    进一步说明,您应该将 setTimeout 语句从 setTimeout(string to eval,delay) 形式更改为 setTimeout(function reference to run, delay)。像这样:

    setTimeout(waitForMsg,1000);
    

    这样您就可以避免不必要的eval 调用。

    进一步,考虑改变

    var json = eval('(' + data + ')');
    

    var json = JSON && JSON.parse ? JSON.parse(data) : eval('(' + data + ')');
    

    这样您就可以在现代浏览器中受益于原生 JSON 解析。

    更好的是,让 jQuery 通过在 ajax 调用中添加 dataType: 'json' 作为参数来反序列化 JSON :)

    【讨论】:

    • 并非总是如此,它解决了眼前的问题。 jQuery 和 $ 是全局变量,你使用 jQuery 时,你觉得它很邪恶吗?
    • 一切都应该限制在有意义的最小范围内。需要全球化的事物也必须是全球化的。这没有。
    • 我不信教,对不起,我太老了,很务实。保持简单,使用工作所需的工具,不要在不需要的复杂性上浪费时间。对于许多小型 javascript 工作。全局变量很好。它可以做得更好/更清洁吗?当然。你需要花时间在上面吗?不。这都是关于成本与收益的关系。务实,理想主义属于学校,而不是现实世界。
    【解决方案2】:

    不要传递要评估的字符串。它效率低下,难以调试并破坏范围:

    setTimeout('waitForMsg()',1000);
    

    传递函数:

    setTimeout(waitForMsg,1000);
    

    【讨论】:

      【解决方案3】:

      您必须在页面范围内的任何函数之外定义 var TimeStamp。

      当您在代码块中定义变量时,它将仅在同一“级别”可见,并且在您从该代码块调用的方法中不可见。

      当您在 ajax 调用中向 TimeStamp 变量写入值时(并且没有使用 'var' 定义它),它将自动定义或重用页面范围内的 TimeStamp 变量,但是由于您尝试读取 TimeStamp(数据: "TimeStamp=" + TimeStamp) 变量在你写入之前,它会产生'未定义'错误。

      无论如何:考虑避免使用页面范围变量的可能性。

      【讨论】:

        猜你喜欢
        • 2020-02-07
        • 2012-12-23
        • 2011-05-10
        • 2011-03-03
        • 2013-01-16
        • 2011-05-26
        相关资源
        最近更新 更多