【问题标题】:What's causing these javascript validation errors (Implied global and already defined var)?是什么导致了这些 javascript 验证错误(隐含的全局和已定义的 var)?
【发布时间】:2009-01-04 15:28:21
【问题描述】:

谁能解释一下原因:

function doAjax() {
    var xmlHttpReq = false;
    try { // Firefox, Opera 8.0+ and Safari
        xmlHttpReq = new XMLHttpRequest();
    }
    catch (e) { // Internet Explorer
        try {
            xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
                alert("Your browser does not support AJAX. Please use an AJAX compatible browser.");
                return false;
            }
        }
    }
    xmlHttpReq.open('GET', 'handler.php', true);
    xmlHttpReq.onreadystatechange = function() {
        if (xmlHttpReq.readyState == 4) {
            var response = xmlHttpReq.responseText;
            handleAjaxResponse(response);
        }
    };
    xmlHttpReq.send(null);
    return true;
}

导致以下验证错误:

Error:

Implied global: ActiveXObject 8, XMLHttpRequest 4, alert 15, handleAjaxResponse 24

Problem at line 10 character 16: 'e' is already defined.

catch (e) {

Problem at line 14 character 20: 'e' is already defined.

catch (e) {

由 JSlint.com javascript 验证器提供

【问题讨论】:

    标签: javascript ajax validation


    【解决方案1】:

    关于第一个错误,这里是exerpt from the JSLint Documentation

    未定义的变量和函数

    JavaScript 最大的问题是它 对全局变量的依赖, 特别隐含的全局变量。 如果变量没有显式 声明(通常使用 var 语句),然后 JavaScript 假设 该变量是全局的。这个可以 掩盖拼写错误的名称和其他 问题。

    JSLint 期望所有变量和 函数在它们被声明之前被声明 使用或调用。这允许它 检测隐含的全局变量。这是 也是很好的做法,因为它使 程序更易于阅读。

    有时文件依赖于 全局变量和函数 在别处定义。你可以 通过包括 文件中列出的注释 你的全局函数和对象 程序取决于,但不是 在您的程序或脚本中定义 文件。

    全局声明可能如下所示 这个:

    /*global getElementByAttribute, breakCycles, hanoi */
    

    全局声明以 /*global。注意没有 g前面的空格。你可以有 许多/*global cmets 随你喜欢。 它们必须出现在使用 他们指定的变量。

    关于您的问题,以下部分最有可能帮助您修复错误:

    一些全局变量可以预定义为 你。选择假设浏览器 (浏览器)选项(请参阅下面的选项) 预定义标准全局 由 web 提供的属性 浏览器,例如窗口和文档 和警觉。选择假设犀牛 (rhino) 选项来预定义全局 犀牛提供的属性 环境。选择假设一个雅虎 Widget(小部件)选项预定义 提供的全局属性 雅虎!小部件环境。

    给出第二个错误是因为您对每个异常(包括嵌套异常)重复使用变量“e”。重命名每个异常的变量以避免这种情况。

    【讨论】:

    • 谢谢,虽然“假设浏览器”似乎并不能解决隐含的全局错误 - 为验证器添加自定义注释对我来说似乎很奇怪,理论上,我的方式没有什么不好做事呢? aka,它实际上是有效的?
    【解决方案2】:

    使用像 jQuery 这样的框架会更明智(特别是如果你真的想支持旧版本的 IE(pre v6)),但我认为你不这样做是有原因的。

    如果 a) 你不嵌套 try-catch 并且 b) 你分解出一组函数会更好,即一个用于获取 Xhr 对象,另一个用于使用 Xhr 对象发出通用 ajax 请求和一个执行您要进行的特定 ajax 调用的外部“doAjax”函数:-

    function getXHR()
    {
        var result = null
        if (window.XMLHttpRequest)
        {
            result = new XMLHttpRequest();
        }
        else
        {
            try { result = new ActiveXObject("MSXML2.XMLHTTP.3.0") }
            catch (e) { }
    
            if (result == null)
            {
                try { result = new ActiveXObject("Microsoft.XMLHTTP") }
                catch (e) { }
            }
        }
        return result; 
    }
    
    
    function ajaxRequest(url, data, callBack)
    {
        var xmlHttpReq = getXHR();
        if (xmlHttpReq)
        {
            xmlHttpReq.open(data != null ? 'GET' : 'POST', url, true);
            xmlHttpReq.onreadystatechange = function()
            {
                if (xmlHttpReq.readyState == 4)
                {
                    //what happens if status is not 200
                    callBack(xmlHttpReq.responseText);
                }
            };
            xmlHttpReq.send(null);
            return true;
        }
        else
        {
            return false;
        }
    }
    
    function doAjax()
    {
         var result = ajaxRequest('handler.php', null, handleAjaxResponse);
         if (!result) alert("Your browser does not support AJAX. Please use an AJAX compatible browser.");
         return result;
    }
    

    进一步的改进是让回调接受一个 XHR 对象而不是基本的 responseText。这会给你更多的灵活性。如果回调函数只是想要文本,它可以使用这个函数:-

    function getTextFromXhr(xhr)
    {
        xhr.onreadystatechange = fnVoid;
        if (xhr.status == 200)
        {
            return xhr.responseText;
        }
        else
        {
            throw {number: xhr.status,
                description: xhr.statusText,
                responseText: xhr.responseText
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您在每个 try/catch 块中重用变量 e。尝试重命名它们以避免冲突。其他问题只是警告您正在使用需要在其他地方定义的东西。

      【讨论】:

      • 谢谢,所以将 Es 重命名为 eg。 e1、e2 和 e3 会更干净吗?它对我来说似乎不是很干净 - 我相信上面的例子是从 W3C 复制的。
      • 不,重命名“e”不会“更干净”。 JSLint 显示错误和警告。这些只是警告,通过使用“e”,您会使先前的错误对象在该块中不可用。如果您需要第二个捕获中的第一个“e”,则需要重命名。我会忽略这个警告。
      • 我也会避免嵌套 try-catch。
      【解决方案4】:

      JSlint 通常会给出很多错误...

      'e' 已经定义对我来说似乎很清楚:) 您对所有 try-catch 语句使用相同的变量。

      【讨论】:

        猜你喜欢
        • 2011-06-05
        • 1970-01-01
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 2011-08-13
        相关资源
        最近更新 更多