13
4

3 回答 3

7

我做了一些实验。看起来每次window.event在 IE 中访问时,都会得到一个新对象:

document.body.onclick = function() {
    var u = window.event, v = window.event;
    console.log(window.event == window.event); // false
    console.log(u == v); // false
    console.log(u == u); // true
    console.log(v == v); // true
    console.log(u == window.event); // false
    console.log(v == window.event); // false
};

因此,每当您检索IE 时window.event,IE 都会创建一个新对象。如果您针对自身(u == uv == v)测试该对象,它就是truewindow.event如果你用另一个对象测试它,它是错误的。

NaN(请注意,这与var a = NaN; console.log(a == a);的行为不同false。)

可以将window.event其视为类似于生成器的东西,更像是window.createCopyOfLastEvent()在 IE 中。 window.event是一个总是返回一个新对象的getter。下面说明了这一点:

document.body.onclick = function() {
    var v = window.event;
    v.a = 1;
    console.log(v.a); // 1
    console.log(window.event.a); // undefined
};

在上面的例子中,window.event.aundefined当它被记录时,因为它引用了一个不同的对象,而不是 where a = 1

为了进一步说明,这种行为可以在纯 JavaScript 中重新创建(在支持 ES5 的浏览器中:IE9,或最新版本的 FF、Chrome 或 Safari):

var weirdObject = Object.create({ }, {
    whoa: {
        get: function() {
            return new Object();
        }
    }
});

console.log(weirdObject.whoa == weirdObject.whoa); // false

或者甚至看起来更陌生:

Object.defineProperty(window, 'ahh', {
    get: function() {
        return Math.random();
    }
});

console.log(ahh == ahh); // false
于 2012-09-18T02:59:35.467 回答
3

更新:阅读:IE Bug (window === top) === false

简而言之——IE 坏了,不能很好地比较主机对象。

并非所有浏览器都支持window.event. 大多数使用event传递给函数的对象。(window.event被认为是 IE 特有的东西,尽管 Chrome 似乎复制了它。)

尝试这个:

 document.getElementById('btn1').onclick = function(event){   
  if (!event) {event = window.event;}

  alert([typeof event, typeof window.event])

  if (window === window)  
    alert('window === window')
  else
    alert('window !== window');

  if (window.event === window.event)  
    alert('window.event === window.event')
  else
    alert('window.event !== window.event' );   
}

}

于 2012-09-18T02:26:48.213 回答
3

比较行为符合 ECMAScript 标准当代码在不支持的浏览器中执行时window.event,我们实际上是在比较两个返回的未定义值true。在 MSIEwindow.event上只是一个MSEventObj接口,这意味着对它的两次不同调用不会返回相同的对象,它们会进行错误的比较。

这意味着,嗯,window.event永远不会相同,所以比较是没有意义的。如果您尝试比较事件类型,您可以通过强制字符串比较来进行鸭子类型比较:

//false, you're either comparing undefined values or different objects
console.log(window.event == window.event);

//true, you're either comparing two "undefined" or "[object MSEventObj]" strings
console.log((""+window.event) === (""+window.event));

我不知道您需要执行此特定检查的实际情况。应通过检查其type属性来确定事件类型:

function doSomething(e) {
  if (!e) var e = window.event;
  alert(e.type);//or whatever
}

请注意,这应该从属于 DOM 的脚本执行,而不是从开发人员工具的控制台执行:

别

跨浏览器事件属性的怪癖概述

于 2012-09-18T03:18:34.740 回答