I think with help of the first operation you just check if such an event is in window object, so it returns true. Two other tell you if such a handler is implemented, and there is no implementation yet you get false.
Can you check the following:
window.onhashchange = function() {}
window['onhashchange'];
yea, anyway it will return true now, because we have defined that variable... So most probably
'onhashchange' in window;
just checks if browser supports it
window['onhashchange']; //returns false
window.onhashchange; //returns false;
just checks if handler already implemented
PS. Also you can be interesting in Javascript IN operator compatibility, here @Andy E wrote:
You should err on the side of caution when using it to check event support. All implementations except Mozilla support "eventname" in element as a test for DOM events, Firefox will result in false here unless a handler is defined.
UPDATE: to see difference between "x in window" and "window.x" (which is equal to window['x']), take a look at the following script and its output:
var foo = {};
console.info( 'bar' in foo ); // false, because no such proeprty
console.info( foo.bar ); // undefined, because no such property
console.info( foo.bar ? 'true' : 'false' ); // 'false' because no such property
foo = { bar: false };
console.info( 'bar' in foo ); // true, because there is such property
console.info( foo.bar ); // false, because this is value of bar property
console.info( foo.bar ? 'true' : 'false' ); // 'false' because foo.bar is false
foo = { bar: 1 };
console.info( 'bar' in foo ); // true, because there is such a property
console.info( foo.bar ); // 1, because this is value of bar proeprty
console.info( foo.bar ? 'true' : 'false' ); // 'true', because foo.bar is 1 (which is not 0 which meant to be false)
foo = { bar: 0 };
console.info( 'bar' in foo ); // true, because there is such a property
console.info( foo.bar ); // 0, because this is value of bar proeprty
console.info( foo.bar ? 'true' : 'false' ); // 'false', because foo.bar is 0 (which meant to be false)
UPDATE2: Detecting event support without browser sniffing - this article shows how to make event detection cross browser (because "event in window" does not work in Mozilla; this article also answers why it is so)