javascript in operator and events
update:
for( i in window)if(i=='onhashchange')console.log(i, window[i]); //prints onchangechange undefined
on browser where onhas开发者_如何学Pythonhchange event is supported I have
'onhashchange' in window; //returns true
window['onhashchange']; //returns false
window.onhashchange; //returns false;
why does the former returns true and the rest returns false?
Could it be simply that the window
object has a property called onhashchange
, but the value of the property is currently null
and therefore considered false?
var a = { 'foo': null }
console.log('foo' in a) // true
console.log(a.foo) // null
console.log(!!a.foo) // false
…where the !!
is a double negation, a trick to convert value to true/false.
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)
精彩评论