{"id":69,"date":"2018-01-09T07:00:14","date_gmt":"2018-01-09T14:00:14","guid":{"rendered":"https:\/\/coreassistance.com\/tips\/?p=69"},"modified":"2018-02-01T11:48:57","modified_gmt":"2018-02-01T18:48:57","slug":"beware-of-typeof","status":"publish","type":"post","link":"https:\/\/coreassistance.com\/tips\/2018\/01\/09\/beware-of-typeof\/","title":{"rendered":"Beware of <code>typeof<\/code>"},"content":{"rendered":"<p>The <code>typeof<\/code> operator in JavaScript is full of strange quirks. Before I show you what to watch out for let&#39;s take a look at what it does correctly.<\/p>\n<p>First of all, <code>typeof<\/code> will always return a string that (supposedly) describes what follows it. Here are some examples that work as expected, with the resulting string shown in a comment following each statement:<\/p>\n<pre><code class=\"javascript\">typeof undefined; \/\/ &#39;undefined&#39;\r\ntypeof true; \/\/ &#39;boolean&#39;\r\ntypeof 42; \/\/ &#39;number&#39;\r\ntypeof &#39;foo&#39;; \/\/ &#39;string&#39;\r\ntypeof function () {}; \/\/ &#39;function&#39;\r\ntypeof { foo: bar }; \/\/ &#39;object&#39;\r\n<\/code><\/pre>\n<p>So far, so good. But what about using <code>typeof<\/code> on an array?<\/p>\n<pre><code class=\"javascript\">typeof [foo, bar]; \/\/ &#39;object&#39;\r\n<\/code><\/pre>\n<p>Well, okay, arrays are <em>technically<\/em> objects in JavaScript, so that&#39;s cool, I guess.<\/p>\n<p>What about <code>null<\/code>?<\/p>\n<pre><code class=\"javascript\">typeof null; \/\/ &#39;object&#39;\r\n<\/code><\/pre>\n<p>So that&#39;s, uh, also an object? Okay, sure.<\/p>\n<p>What about a class?<\/p>\n<pre><code class=\"javascript\">typeof class baz {}; \/\/ &#39;function&#39;\r\n<\/code><\/pre>\n<p>So a class is a function? Again, technically true, but maybe not the result we were expecting.<\/p>\n<p>What about <code>NaN<\/code>, which literally stands for &quot;not a number&quot;?<\/p>\n<pre><code class=\"javascript\">typeof NaN; \/\/ &#39;number&#39;\r\n<\/code><\/pre>\n<p>Oh, JavaScript, you precious thing.<\/p>\n<p>Now that you know to watch out for those unexpected results, let&#39;s talk about how to get some more useful information from unknown types.<\/p>\n<p>The <code>Object<\/code> class in JavaScript has a <code>toString<\/code> method prototype that can be called directly to produce a string that&#39;s a bit more descriptive and useful:<\/p>\n<pre><code class=\"javascript\">Object.prototype.toString.call(undefined); \/\/ &#39;[object Undefined]&#39;\r\nObject.prototype.toString.call(true); \/\/ &#39;[object Boolean]&#39;\r\nObject.prototype.toString.call(42); \/\/ &#39;[object Number]&#39;\r\nObject.prototype.toString.call(&#39;foo&#39;); \/\/ &#39;[object String]&#39;\r\nObject.prototype.toString.call(function () {}); \/\/ &#39;[object Function]&#39;\r\nObject.prototype.toString.call({ foo: bar }); \/\/ &#39;[object Object]&#39;\r\nObject.prototype.toString.call([foo, bar]); \/\/ &#39;[object Array]&#39;\r\nObject.prototype.toString.call(null); \/\/ &#39;[object Null]&#39;\r\n<\/code><\/pre>\n<p>Much better. We can now tell the difference between an object, an array, and <code>null<\/code>!<\/p>\n<p>Alas, this method still falls short when it comes to classes and <code>NaN<\/code>:<\/p>\n<pre><code class=\"javascript\">Object.prototype.toString.call(class baz {}); \/\/ &#39;[object Function]&#39;\r\nObject.prototype.toString.call(NaN); \/\/ &#39;[object Number]&#39;\r\n<\/code><\/pre>\n<p>The class situation makes sense; <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Classes\">classes in JavaScript are really just fancy syntax for special functions<\/a>, but it would be nice to see something like <code>[object Class]<\/code> returned here all the same.  Oh well.<\/p>\n<p>So, be careful when using <code>typeof<\/code>, and use <code>Object.prototype.toString.call()<\/code> if you need something a bit more descriptive.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An examination of some unusual JavaScript behavior and how to (mostly) work around it.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-69","post","type-post","status-publish","format-standard","hentry","category-javascript"],"_links":{"self":[{"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/posts\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/comments?post=69"}],"version-history":[{"count":10,"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/posts\/69\/revisions"}],"predecessor-version":[{"id":324,"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/posts\/69\/revisions\/324"}],"wp:attachment":[{"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/media?parent=69"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/categories?post=69"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coreassistance.com\/tips\/wp-json\/wp\/v2\/tags?post=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}