true !== true in IE11 javascript

true !== true in IE11 javascript

本文关键字:true javascript IE11 in      更新时间:2023-09-26

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

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

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

比较代码为:

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

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

$ wind是web应用程序的主(顶部)窗口,用于加载SmartClient javascript。

isc. isaccanvas(..)是一个返回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;
}

在不同的测试运行中,警报在不同的通过次数后显示。例如,在第一次运行中,它通过了358698次,在第二次运行中,它通过了330125次…

有谁知道是什么问题吗?"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

这个问题是由IE11的一个bug引起的。

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

安装此更新解决了问题。

我们得到的技术细节是:

所讨论的bug与回收JIT函数和跨站点的bug有关。一个跨站点的函数正在被回收。然后我们将entryPoint更改为InterpreterThunk,在此过程中丢失了跨站点的thunk。调用此函数时不会进行封送处理。在有问题的repro中,我们最终得到了一个来自不同scriptContext的布尔True对象,当与===比较时,它与当前scriptContext中的对象不匹配。

99%的问题在SmartGWT。我建议您将这个问题报告给SmartGWT团队,当然要使用最新的GWT编译器。我们以前处理过SmartGWT,根据我的经验,我应该说它当时是一个非常多bug的库。

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

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

希望对你有帮助。