Javascript 为什么要抛出';未捕获引用错误:未定义var';定义var时

Javascript 为什么要抛出';未捕获引用错误:未定义var';定义var时,javascript,Javascript,我的JavaScript函数 function B_modeWindow (id,cords) { loading(); var xmlhttp; if (window.XMLHttpRequest) { xmlhttp=new XMLHttpRequest(); } else { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onrea

我的JavaScript函数

function B_modeWindow (id,cords) {  
    loading();

    var xmlhttp;

    if (window.XMLHttpRequest) {
        xmlhttp=new XMLHttpRequest();
    } else {
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {

            var cords = document.getElementById(cords)
            cords.innerHTML=xmlhttp.responseText;
            var xy = cords.split("x");          
            hideloading();
        }
    }

    xmlhttp.open("GET","processMapEdit.php?id="+id+"&x="+xy[0]+"&y="+xy[1],true);
    xmlhttp.send();
}
返回:

Uncaught ReferenceError: xy is not defined 
在:


似乎xy不在那里,但它的定义仅在上面5行!这里有什么问题?

您需要在
onreadystatechange
函数之外定义
xy
变量,以便在您使用它的地方可以使用它

这应该起作用:

function B_modeWindow (id,cords) {  
    var xy = null; // defined xy here

    loading();

    var xmlhttp;

    if (window.XMLHttpRequest) {
        xmlhttp=new XMLHttpRequest();
    } else {
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {

            var cords = document.getElementById(cords)
            cords.innerHTML=xmlhttp.responseText;
            xy = cords.split("x");          // removed var keyword here
            hideloading();
        }
    }

    xmlhttp.open("GET","processMapEdit.php?id="+id+"&x="+xy[0]+"&y="+xy[1],true);
    xmlhttp.send();
}

请注意,默认情况下ajax调用是异步的,因此即使作用域是固定的,
xy
变量也可能没有您想要的。在这种情况下,您必须以某种方式在ajax请求中使用回调来捕获实际值

xy
仅在匿名函数
xmlhttp.onreadystatechange=function(){//xy}
的作用域中定义。因此,在这个匿名函数之外无法访问它。请改用以下方法:

function B_modeWindow (id,cords) {  
    loading();

    var xmlhttp;

    if (window.XMLHttpRequest) {
        xmlhttp=new XMLHttpRequest();
    } else {
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    var xy = cords.split("x"); 

    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            var cordsElement = document.getElementById(cords);
            cordsElement.innerHTML=xmlhttp.responseText;      
            hideloading();
        }
    }

    xmlhttp.open("GET","processMapEdit.php?id="+id+"&x="+xy[0]+"&y="+xy[1],true);
    xmlhttp.send();
}
这样,
xy
的范围就是函数
B_modeWindow
,而不是一个异常函数

另外,请注意,即使如果您可以在匿名函数之外访问
xy
(您不能),也不会定义
xy
,因为您仅在AJAX请求完成时定义它,并且您需要使用它来实际进行AJAX调用


另一个建议是为
跳线
使用不同的变量名。您首先使用它按
x
分割其内容,然后定义另一个
cords
变量来分配DOM元素。虽然这是可行的,但可能会让人困惑。

您将声明放在了错误的函数中。此外,您还需要为回调中的
跳线
指定一个不同的名称,否则会出现故障

function B_modeWindow (id,cords) {
    var xy = cords.split("x");

    loading();

    var xmlhttp;

    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            var cordsElement = document.getElementById(cords);
            cordsElement.innerHTML = xmlhttp.responseText;
            hideloading();
        }
    };

    xmlhttp.open("GET", "processMapEdit.php?id=" + id + "&x=" + xy[0] + "&y=" + xy[1], true);
    xmlhttp.send();
}

是的,xy是定义的,但它是在大括号内定义的-它超出范围,或者在你到达问题线时停止退出*编辑:见下面的评论。我的这句话完全错了*

要修复它,只需在
xmlhttp.onreadystatechange=function()行上方定义xy即可。

或者更好的是,在func的顶部。

它们不在同一范围内定义,因此不,它实际上没有定义。但是,您希望如何使用发送后将获得的值打开请求?您可以说
var xy=cords.split(“x”)
需要是全局的,对吗?不一定是全局的,它可以在
B_modeWindow
中声明,它不是关于花括号,而是关于函数;这个函数当时还没有运行。呃,是的,它是关于花括号的——在这个例子中,它们只是用来指定匿名函数的开始和结束。然而,你确实很好地指出了他们所处的区块还没有运行-有些不相关,但仍然很好。不,这不是关于花括号。JavaScript没有块作用域。试试看:
var a=5;{var a=10;}console.log(a);//10
谢谢你,minitech.:拇指:我最谦虚的道歉,你可以接受也可以拒绝。现在它说
未捕获的TypeError:Object#没有方法“拆分”B_modeWindow.js:22 B_modeWindow B_modeWindow.js:22(匿名函数)
@user1656447:请尝试我的更新。我被称为
cords
的重复变量名弄糊涂了。现在应该可以了。
function B_modeWindow (id,cords) {
    var xy = cords.split("x");

    loading();

    var xmlhttp;

    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            var cordsElement = document.getElementById(cords);
            cordsElement.innerHTML = xmlhttp.responseText;
            hideloading();
        }
    };

    xmlhttp.open("GET", "processMapEdit.php?id=" + id + "&x=" + xy[0] + "&y=" + xy[1], true);
    xmlhttp.send();
}