【问题标题】:true !== true in IE11 javascripttrue !== true 在 IE11 javascript 中
【发布时间】:2014-07-11 11:59:22
【问题描述】:

我们在 IE11 上的 Web 应用程序中遇到了一个非常奇怪的问题(其他 IE 版本工作正常)。 该应用程序基于 SmartGWT (http://www.smartclient.com/product/smartgwt.jsp) - SmartClient javascript 框架上的 GWT 包装器。

IE11 进入永无止境的循环。 它非常随机地发生,我们没有步骤来重现它。我们应用程序的复杂性使得无法发布代码示例。 最常见的情况发生在用户使用应用程序时,然后他们最小化浏览器窗口并在一段时间后恢复它并尝试继续工作。

无休止的循环是由奇怪的比较结果引起的,当表达式 'true === true' 结果为假时。

对比代码为:

$wnd.isc.isA.Canvas(obj) === true

代码在包含由 GWT 编译的 javascript 的 iframe 范围内执行。

$wnd 是加载 SmartClient javascripts 的 Web 应用程序的主(顶部)窗口。

isc.isACanvas(..) 是一个返回 true 或 false 的方法,取决于作为参数传递的对象是否属于 Canvas 类型 - Canvas 是 SmartClient 框架中的一个特殊类,而不是 HTML Canvas 元素。

isc.isA.Canvas = function (object) {
  return (object != null && object._isA_Canvas);
}

在创建对象时,对象上的_isA_Canvas 设置为true(布尔值true 不是字符串形式的'true')。

我已经在使用有问题的比较的部分添加了一些测试代码 - 这是一个简化版本:

var trueCheckCount = 0;
function isCreated(id){
  var obj = $wnd.window[id];    // objects are stored in window by id

  var comparisonResult = $wnd.isc.isA.Canvas(obj) === true;

  if (!comparisonResult ) {
    if ($wnd.isc.isA.Canvas(obj) == true) {
      alert("TRUE != TRUE  (was OK: " + trueCheckCount + "x before)");
    } else {
      trueCheckCount++;
    }
  }

  return comparisonResult;
}

在不同的测试运行中,警报会在不同的通过次数后显示。例如。第一次通过了 358 698 次,第二次通过了 330 125 次……

有人知道可能是什么问题吗? 'true !== true' 怎么可能发生?

环境:

IE11 (Windows7/8)
SmartGWT: v9.0p_2014-03-02/LGPL Development Only (built 2014-03-02)
GWT: 2.4

在屏幕截图中可以看到一些额外的调试信息: https://drive.google.com/file/d/0B8h18b-AMFzXa3NZZ2dOX2txb1k/edit?usp=sharing

【问题讨论】:

  • 等一下.. 我没有阅读所有内容,但这很有趣。您是说如果您在控制台中执行 true !== true 会显示为 true?
  • 您也应该提醒$wnd.isc.isA.Canvas(obj) 的值,以确保它在这些时刻设置为true

标签: javascript gwt smartgwt internet-explorer-11


【解决方案1】:

问题是由 IE11 中的错误引起的。

MS 发布了修复程序。它包含在 12 月 Internet Explorer 累积更新 KB3008923 中。

安装此更新解决了我们的问题。

我们得到的技术细节是:

有问题的错误与回收 JIT 函数和跨站点 thunk 有关。 具有跨站点 thunk 的函数正在被回收。 然后我们将 entryPoint 更改为 InterpreterThunk,在此过程中丢失了跨站点 thunk。 调用此函数时不进行编组。 在有问题的重现中,我们最终得到了来自不同 scriptContext 的 Boolean True 对象,与 === 比较时,该对象与当前 scriptContext 中的对象不匹配。

【讨论】:

    【解决方案2】:

    SmartGWT 有 99% 的问题。我建议您将此问题报告给 SmartGWT 团队并使用最新的 GWT 编译器。我们之前处理过 SmartGWT,根据我的经验,我应该说当时它是一个非常错误的库。

    【讨论】:

    • 我已经向 SmartGWT 团队报告了这个问题,但至今没有任何回应。
    【解决方案3】:

    您的调试代码中有两个问题可能会给您带来错误的印象:

    if ($wnd.isc.isA.Canvas(obj) == true) {
        alert("TRUE != TRUE  (was OK: " + trueCheckCount + "x before)");
    } else {
    

    首先,您在这里进行了双等比较,之前您进行了=== 比较。这些是不同的,如果被测试的变量不是布尔值,则会给出不同的结果。

    例如,如果 $wnd.isc.isA.Canvas(obj) 输出的是整数 1 或类似的东西,而不是 true,那么您将得到您所描述的问题。

    与其做另一个比较,为什么不使用JSON.stringify获得变量内容的准确图片

    console.log(JSON.stringify($wnd.isc.isA.Canvas(obj)));
    

    这将准确地向您显示值是什么,然后应该相当清楚地告诉您为什么比较没有达到您的预期。

    其次,使用alert() 框来显示错误不是一个好主意,尤其是在复杂的应用程序中。您应该始终使用console.log() 而不是alert() 进行调试,因为alert() 会导致一些JS 代码改变其行为,这会使调试变得非常困难。

    这是因为alert() 在显示时阻止了 JS 的执行,这意味着在此期间触发的任何事件处理程序或其他异步代码最终都可能超出预期的顺序。

    鉴于提供的代码示例,我认为这不一定是您的问题,但是如果您在任何地方有任何 Ajax 调用、setInterval()s 或其他类似的异步代码,那么您确实需要避免使用 @ 987654334@ 用于调试目的。

    希望对您有所帮助。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多