📜 ⬆️ ⬇️

Browser Behaviors with typeof and toString

Today I started to write a project, of which nonkilling timers with Workers, which withstand a complete clearTimeout / clearInterval brute force, were part of. One of the conditions was that the worker or other functions / objects can be replaced before running the script. For this, I wrote the functions isNativeObject() , isNativeFunction() , each has a dozen conditions and define the substitution / non-substitution of the function / object and indirect signs pointing to "mucking".

But it’s not about these functions, and certainly not about my project. While running all sorts of native objects, I came across a blatantly different behavior of browsers when processing objects with typeof and toString.

For example, I was extremely struck by the fact that absolutely all browsers give different values ​​to
 Worker.prototype + ""; // FF 3.6 [xpconnect wrapped native prototype] // Op 11 [object DedicatedWorkerPrototype] // Sa 4 [object WorkerPrototype] // Ch 10 [object Object] 

Safari in all native designers and prototypes slips Prototype, Constructor - [object WorkerConstructor], [object WorkerPrototype]
')
The article describes other interesting cases of browser behavior 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 the code in toString:
 (function(){return'a'+'b';}).toString(); // function () { // return "ab"; // } 

Firefox throws an exception when trying to change navigator.userAgent

Opera 11


In opera, it's 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 got it from someone?
Opera allows you to change navigator.userAgent

Safari and Mobile Safari


Safari, apart from its Prototype, Constructor prefixes has the following feature - all of its native objects are typeof === 'object', although some (XHR and Worker) must have a 'function'.
 RegExp.prorotype + "" // // -    IE /(?:)/ 

Safari does not change navigator.userAgent and does not throw an exception.

IE 8


From everything that I checked, IE could only recognize 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 have been fixed, except that the [native code] functions are still full \ n

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 table for browsers and objects: goo.gl/tD1jr
Tester Code: jsfiddle.net/azproduction/V4LeE

Conclusion


Although all browsers (not 8) are acid 3, but they still have many, many bugs in detail. The fixed typeof and toString responses are very important for JavaScript with its duck typing.

The study involved the following objects: 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 didn’t separate out the analysis of flights with HTMLElement separately - nonsense is happening in all browsers.

PS I will be grateful to those who will scan other mobile browsers (Chrome Mobile, Opera Mobile) - throw the tester issue to me in the LAN. If you want to add some of your own test - add it to the end of the tester with a link to the comment - I will later update the table.

UPD Added Firefox 4, IE 9 (thanks to hf35 ), Mobile Safari iOS 4.2.1, ws for Opera (thanks to SKYnv )
Added querySelectorAll, getElementsByTagName, childNodes

UPD2 Added answers for each object on Object.prototype.toString (...)

Source: https://habr.com/ru/post/115841/


All Articles