变量无法设置为“未定义”

9
这是非常奇怪的行为(似乎只出现在Mac上的Chrome浏览器),很多代码似乎被完全跳过,应该具有值的变量设置为“未定义”。 以下是Chrome开发工具中的屏幕截图。请注意,第817行从未被触及!然而833被触及,我们看到的是一个异常被触及,我查找了调用堆栈以找到这个问题。还要注意,“loc”,“lon”和“tc”变量都是未定义的,这在理论上是不可能的,因为它们分别在822行、823/824行和827/831行被计算出来。如果计算出错,这些变量的值应该是NaN(不是数字)。 以下是实际代码:
function getCircle2(latin, lonin, radius) {
    var locs = new Array();
    var lat1 = latin * Math.PI / 180.0;
    var lon1 = lonin * Math.PI / 180.0;
    var d = radius / 3956;
    var x;
    for (x = 0; x <= 360; x++) {
        var tc = (x / 90) * Math.PI / 2;
        var lat = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) * Math.sin(d) * Math.cos(tc));
        lat = 180.0 * lat / Math.PI;
        var lon;
        if (Math.cos(lat1) == 0) {
            lon = lonin; // endpoint a pole
        }
        else {
            lon = ((lon1 - Math.asin(Math.sin(tc) * Math.sin(d) / Math.cos(lat1)) + Math.PI) % (2 * Math.PI)) - Math.PI;
        }
        lon = 180.0 * lon / Math.PI;
        var loc = new VELatLong(lat, lon);
        locs.push(loc);
    }
    return locs;
}

有人能为这个巫术提供一些帮助吗?为什么在Mac上使用Chrome时忽略断点且变量具有不正确的值!?

编辑:

看来我已经修复了错误。我所做的就是将破坏代码隔离在自己的函数中,调用一次该函数,如果它抛出异常,则再次调用它,现在似乎100%有效。我仍然非常好奇问题的根本原因是什么。

//new function to isolate the exception
function getCirclePointOnRadius(deg, lat1, lon1, d, attempt) {
    attempt = attempt || 1;
    var maxAttempts = 2;
    try {
        var tc = (deg / 90) * Math.PI / 2;
        var lat = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) * Math.sin(d) * Math.cos(tc));
        lat = 180.0 * lat / Math.PI;
        var lon;
        if (Math.cos(lat1) == 0) {
            lon = lonin; // endpoint a pole
        }
        else {
            lon = ((lon1 - Math.asin(Math.sin(tc) * Math.sin(d) / Math.cos(lat1)) + Math.PI) % (2 * Math.PI)) - Math.PI;
        }
        lon = 180.0 * lon / Math.PI;
        var loc = new VELatLong(lat, lon);
        return loc;
    }
    catch (e) {
        console.log2('Error when gathering circle point "' + e + '", trying again', deg, lat1, lon1);
        if (attempt < maxAttempts) {
            return getCirclePointOnRadius(deg, lat1, lon1, ++attempt);
        }
        else {
            return 0;
        }
    }
}

然后我用以下代码替换了原本包含逻辑的循环(在getCircle2函数中):

    for (x = 0; x <= 360; x++) {
        locs.push(getCirclePointOnRadius(x, lat1, lon1, d));
    }

你是在使用本地文件调试还是在像jsfiddle/codepen这样的网站上进行调试? - A1rPun
在Windows上的Chrome浏览器上工作良好吗? - Omri Aharon
根据我们的QA测试,Chrome在Windows上运行良好,而我个人在Windows上也无法重现错误。 - KJ Price
2
由于异常是VEException,看起来它是在外部资源中定义的,我想根本原因是加载JavaScript资源的时间问题。例如,我曾经遇到过许多Google Chrome引发load事件的问题,这些事件是在DOM尚不可用的外部SVG资源上引发的。如果是这种情况,您可以使用setTimeout(fn, 0)而不是使用异常处理作为解决方法。 - Jeremy
2
for 循环中的作用域并不是真正的独立执行上下文。我猜测 for 循环内部的变量在循环开始之前被初始化,而此时 x 还没有任何值,因此它们会初始化为 undefined。当您将其重构为单独的函数时,您设置了初始化顺序。我不知道为什么只有 Mac 显示出这种行为,尽管如此。 - Gil Elad
显示剩余4条评论
1个回答

3

是的,西蒙,我认为你说得很对。阅读文章似乎就是答案。使用的变量被引用到各个地方,甚至似乎存在于全局作用域中。 - KJ Price

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接