true!==在IE11 javascript中为true

时间:2014-07-11 11:59:23

标签: javascript gwt smartgwt internet-explorer-11

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

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

永无止境的周期是由奇怪的比较结果引起的,当表达式为真时===真'导致错误。

比较代码是:

$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'曾经发生过?

环境:

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

3 个答案:

答案 0 :(得分:0)

SmartGWT中的问题是99%。我建议您将此问题报告给SmartGWT团队并使用最新的GWT编译器。我们之前和之后处理过SmartGWT,我应该说这是一个非常错误的库。

答案 1 :(得分:0)

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

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()或其他类似的异步代码,那么您确实需要避免使用alert()进行调试。

希望有所帮助。

答案 2 :(得分:0)

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

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

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

我们得到的技术细节是:

有问题的bug与回收JIT功能和跨站点thunks有关。 具有跨站点thunk的功能正在回收。 然后我们将entryPoint更改为InterpreterThunk,从而丢失了流程中的跨站点thunk。 调用此函数时未完成编组。 在有问题的repro中,我们最终得到了一个来自不同scriptContext的布尔True对象,当与===进行比较时,该对象与当前scriptContext中的对象不匹配。