<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Saboor Bhutta</title>
    <description>The latest articles on DEV Community by Saboor Bhutta (@saboor_bhutta).</description>
    <link>https://dev.to/saboor_bhutta</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1695314%2F2dcc8b97-a9af-46b5-bbf6-053e587e3144.png</url>
      <title>DEV Community: Saboor Bhutta</title>
      <link>https://dev.to/saboor_bhutta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saboor_bhutta"/>
    <language>en</language>
    <item>
      <title>JavaScript’s not-so-obvious type coercion examples</title>
      <dc:creator>Saboor Bhutta</dc:creator>
      <pubDate>Mon, 02 Jun 2025 05:55:20 +0000</pubDate>
      <link>https://dev.to/saboor_bhutta/javascripts-not-so-obvious-type-coercion-examples-1lio</link>
      <guid>https://dev.to/saboor_bhutta/javascripts-not-so-obvious-type-coercion-examples-1lio</guid>
      <description>&lt;p&gt;
  JavaScript’s type coercion and dynamic typing system are full of subtle (and sometimes surprising) behaviors.
  Understanding these quirks can make you much more confident and effective as a JS developer.
&lt;/p&gt;

&lt;p&gt;
  Here’s a list of not-so-obvious JavaScript type coercion examples, grouped into categories with explanations:
&lt;/p&gt;

&lt;h2&gt;1. String vs Number Comparison&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Expression&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
    &lt;th&gt;Reason&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;'10' &amp;lt; '2'&lt;/td&gt;
    &lt;td&gt;true&lt;/td&gt;
    &lt;td&gt;Lexicographic comparison: '1' comes before '2'&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;'10' &amp;lt; 2&lt;/td&gt;
    &lt;td&gt;false&lt;/td&gt;
    &lt;td&gt;string '10' is coerced to number 10&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;'5' == 5&lt;/td&gt;
    &lt;td&gt;true&lt;/td&gt;
    &lt;td&gt;string '5' is coerced to number 5&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;'5' === 5&lt;/td&gt;
    &lt;td&gt;false&lt;/td&gt;
    &lt;td&gt;strict equality, no type coercion&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;strong&gt;Rule:&lt;/strong&gt; Loose equality (==) allows type coercion. Strict equality (===) does not.
&lt;/blockquote&gt;

&lt;h2&gt;2. Falsy Values&lt;/h2&gt;

&lt;p&gt;JavaScript has falsy values that act like false in boolean contexts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Expression&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean(' ')&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean(0)&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean(null)&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean(undefined)&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean(NaN)&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean([])&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;Boolean({})&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;strong&gt;Note:&lt;/strong&gt; [] and {} are truthy, even though they're empty.
&lt;/blockquote&gt;

&lt;h2&gt;3. Array and Object Coercion&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Expression&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
    &lt;th&gt;Reason&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[] + []&lt;/td&gt;
&lt;td&gt;' '&lt;/td&gt;
&lt;td&gt;both arrays are coerced to strings → ' ' + ' '&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[] + {}&lt;/td&gt;
&lt;td&gt;'[object Object]'&lt;/td&gt;
&lt;td&gt;[] → ' ',  {} → '[object Object]' &lt;br&gt; ' ' + '[object Object]' → '[object Object]'&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[] == false&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;[] → ' ' → ' ' == false → true&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[0] == false&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;[0] → '0' → 0 == false → true&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[1,2] + [3,4]&lt;/td&gt;
&lt;td&gt;'1,23,4'&lt;/td&gt;
&lt;td&gt;arrays are stringified → '1,2' + '3,4'&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;4. Arithmetic with Non-numbers&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Expression&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
    &lt;th&gt;Reason&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;'5' - 2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;'5' is coerced to number&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;'5' + 2&lt;/td&gt;
&lt;td&gt;'52'&lt;/td&gt;
&lt;td&gt;'+' triggers string concatenation&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;null + 1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;null → 0&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;undefined + 1&lt;/td&gt;
&lt;td&gt;NaN&lt;/td&gt;
&lt;td&gt;undefined → NaN&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;true + 1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;true → 1&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;false + 1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;false → 0&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;"abc" * 33&lt;/td&gt;
&lt;td&gt;NaN&lt;/td&gt;
&lt;td&gt;Cannot coerce "abc" to Number → NaN&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;33 / 0&lt;/td&gt;
&lt;td&gt;Infinity&lt;/td&gt;
&lt;td&gt;Division by zero → Infinity&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;0 / 0&lt;/td&gt;
&lt;td&gt;NaN&lt;/td&gt;
&lt;td&gt;Undefined division → NaN&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;+&lt;/code&gt; operator behaves differently depending on whether one side is a string — it prefers string concatenation over numeric addition.
&lt;/blockquote&gt;

&lt;h2&gt;5. Equality Weirdness&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Expression&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
    &lt;th&gt;Reason&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;null == undefined&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;only loosely equal to each other&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;null === undefined&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;different types&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[] == ' '&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;[] → ' '&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[null] == ' '&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;[null] → ' '&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;[undefined] == ' '&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;[undefined] → ' '&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;{} == {} OR [] == []&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;different references&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;NaN == NaN&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;NaN is not equal to anything, even itself&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;6. &lt;code&gt;typeof&lt;/code&gt; Quirks&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Expression&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
    &lt;th&gt;Reason&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;typeof null&lt;/td&gt;
&lt;td&gt;'object'&lt;/td&gt;
&lt;td&gt;Legacy bug in JavaScript&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;typeof NaN&lt;/td&gt;
&lt;td&gt;'number'&lt;/td&gt;
&lt;td&gt;NaN is actually a special kind of &lt;b&gt;number&lt;/b&gt;
&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;typeof [] , typeof {}&lt;/td&gt;
&lt;td&gt;'object'&lt;/td&gt;
&lt;td&gt;Arrays are objects too&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;typeof function(){}&lt;/td&gt;
&lt;td&gt;'function'&lt;/td&gt;
&lt;td&gt;Functions are a special kind of object&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Best Practices&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Always use &lt;code&gt;===&lt;/code&gt; instead of &lt;code&gt;==&lt;/code&gt; unless you're very sure about coercion.&lt;/li&gt;
  &lt;li&gt;Use &lt;code&gt;Number()&lt;/code&gt;, &lt;code&gt;Boolean()&lt;/code&gt;, or &lt;code&gt;String()&lt;/code&gt; explicitly when converting types.&lt;/li&gt;
  &lt;li&gt;For checking arrays: &lt;code&gt;Array.isArray(value)&lt;/code&gt;
&lt;/li&gt;
  &lt;li&gt;For checking NaN: &lt;code&gt;Number.isNaN(value)&lt;/code&gt; or &lt;code&gt;Object.is(value, NaN)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
