
Behaviors of browsers with typeof and toString
Today I started writing a project, part of which were indestructible timers with Workers that withstand a complete brute force clearTimeout / clearInterval. One of the conditions was that the worker or other functions / objects can be replaced before running the script. To do this, I wrote a function
But here it is not a matter of these functions, much less of my project. Running all kinds of native objects, I came across a blatantly different browser behavior when processing objects with typeof and toString.
For example, I was very struck by the fact that absolutely all browsers give different values on
Safari prototype into all native constructors and prototypes Prototype, Constructor -
This article describes other interesting cases of behavior of browsers with typeof and toString.
Firefox optimizes constants, replaces quotes, and aligns code in toString:
Firefox throws an exception when trying to change navigator.userAgent
The opera is more or less good with typeof and toString, but the following behavior is suspicious:
The names are similar to Safari, who "borrowed" from whom?
Opera allows you to change navigator.userAgent
Safari, in addition to its Prototype, Constructor prefixes, has the following feature - all its native objects have typeof === 'object', although some (XHR and Worker) must be 'function'.
Safari does not change navigator.userAgent and does not throw an exception
From everything that I checked IE was able to identify only XMLHttpRequest and RegExp, so the list for it is not so big:
IE 8 throws an exception when trying to change navigator.userAgent, IE 9 behaves like a safari.
In IE 9, all of the above bugs were fixed, except that in [native code] functions there are still \ n full
Chrome has only one "feature":
Chrome, like safari, does not change navigator.userAgent and does not throw an exception
Summary, full table of browsers and objects: goo.gl/tD1jr
Tester code: jsfiddle.net/azproduction/V4LeE
Although all browsers (not 8) pass acid 3, but there are still many many bugs in the details. Fixed responses to typeof and toString are very important for JavaScript with its duck typing.
The objects involved in the study: Worker, XMLHttpRequest, CanvasContext, CanvasContext3D, Storage, WebSocket, FileReader, EventSource, navigator.geolocation, HTMLElement, RegExp, querySelectorAll, getElementsByTagName, childNodes.
Browsers: Firefox 4, Firefox 3.6, Opera 11, Safari, IE 8, IE 9, Chrome 10 beta, Mobile Safari iOS 4.2.1
For technical reasons, I can’t add all mobile browsers. I did not separate the debriefing with HTMLElement separately - in all browsers there is nothing.
PSI will be grateful to those who scan the rest of the mobile browsers (Chrome Mobile, Opera Mobile) - throw the tester delivery to me in the LAN. If you want to add some kind of your test - add it to the end of the tester with a link to the comment - I will update the table later.
UPD Added Firefox 4, IE 9 (thanks hf35 ), Mobile Safari iOS 4.2.1, ws for Opera (thanks SKYnv )
Added querySelectorAll, getElementsByTagName, childNodes
UPD2 Added answers for each object on Object.prototype.toString (...)
isNativeObject()
, isNativeFunction()
each has a dozen conditions and determine the substitution / not substitution of a function / object and indirect signs indicating "swindle". But here it is not a matter of these functions, much less of my project. Running all kinds of native objects, I came across a blatantly different browser behavior when processing objects with typeof and toString.
For example, I was very struck by the fact that absolutely all browsers give different values on
Worker.prototype + "";
// FF 3.6 [xpconnect wrapped native prototype]
// Op 11 [object DedicatedWorkerPrototype]
// Sa 4 [object WorkerPrototype]
// Ch 10 [object Object]
Safari prototype into all native constructors and prototypes Prototype, Constructor -
[object WorkerConstructor], [object WorkerPrototype]
This article describes other interesting cases of behavior of browsers with typeof and toString.
Firefox 3.6, Firefox 4
typeof Worker // function
Worker + "" // [object Worker] - не понятно почему [object ...]
Worker.prototype + "" // [xpconnect wrapped native prototype] ???
// аналогично с XMLHttpRequest и FileReader
typeof localStorage.prototype // object - во всех других браузерах undefined
localStorage.prototype + "" // null
navigator.geolocation + "" // [object GeoGeolocation] - не понятно какие ещё геолокации есть кроме Geo- во всех остальных браузерах [object Geolocation]
Firefox optimizes constants, replaces quotes, and aligns code in toString:
(function(){return'a'+'b';}).toString();
// function () {
// return "ab";
// }
Firefox throws an exception when trying to change navigator.userAgent
Opera 11
The opera is more or less good with typeof and toString, but the following behavior is suspicious:
Worker.prototype + "" // [object DedicatedWorkerPrototype] - Dedicated!
XMLHttpRequest.prototype + "" // [object XMLHttpRequestPrototype]
EventSource.prototype + "" // [object EventSourcePrototype]
The names are similar to Safari, who "borrowed" from whom?
Opera allows you to change navigator.userAgent
Safari and Mobile Safari
Safari, in addition to its Prototype, Constructor prefixes, has the following feature - all its native objects have typeof === 'object', although some (XHR and Worker) must be 'function'.
RegExp.prorotype + "" // // - у всех кроме IE /(?:)/
Safari does not change navigator.userAgent and does not throw an exception
IE 8
From everything that I checked IE was able to identify only XMLHttpRequest and RegExp, so the list for it is not so big:
typeof XMLHttpRequest // object
XMLHttpRequest.prototype + "" // [Interface prototype object]
RegExp + "" // \nfunction RegExp() {\n [native code]\n}\n - к чему лишние переносы строк не ясно
RegExp.prorotype + "" // // - как и у Сафари
typeof document.getElementById // object o_O
IE 8 throws an exception when trying to change navigator.userAgent, IE 9 behaves like a safari.
In IE 9, all of the above bugs were fixed, except that in [native code] functions there are still \ n full
Chrome 10 beta
Chrome has only one "feature":
Worker.hasOwnProperty("toString") // true - не понятно почему бы не брать с прототипа...
Chrome, like safari, does not change navigator.userAgent and does not throw an exception
That's not all
Summary, full table of browsers and objects: goo.gl/tD1jr
Tester code: jsfiddle.net/azproduction/V4LeE
Conclusion
Although all browsers (not 8) pass acid 3, but there are still many many bugs in the details. Fixed responses to typeof and toString are very important for JavaScript with its duck typing.
The objects involved in the study: Worker, XMLHttpRequest, CanvasContext, CanvasContext3D, Storage, WebSocket, FileReader, EventSource, navigator.geolocation, HTMLElement, RegExp, querySelectorAll, getElementsByTagName, childNodes.
Browsers: Firefox 4, Firefox 3.6, Opera 11, Safari, IE 8, IE 9, Chrome 10 beta, Mobile Safari iOS 4.2.1
For technical reasons, I can’t add all mobile browsers. I did not separate the debriefing with HTMLElement separately - in all browsers there is nothing.
PSI will be grateful to those who scan the rest of the mobile browsers (Chrome Mobile, Opera Mobile) - throw the tester delivery to me in the LAN. If you want to add some kind of your test - add it to the end of the tester with a link to the comment - I will update the table later.
UPD Added Firefox 4, IE 9 (thanks hf35 ), Mobile Safari iOS 4.2.1, ws for Opera (thanks SKYnv )
Added querySelectorAll, getElementsByTagName, childNodes
UPD2 Added answers for each object on Object.prototype.toString (...)