{"id":2849,"date":"2023-12-28T09:00:00","date_gmt":"2023-12-28T10:00:00","guid":{"rendered":"https:\/\/vfflogs.com\/?p=2849"},"modified":"2023-12-29T10:38:45","modified_gmt":"2023-12-29T10:38:45","slug":"making-sense-of-senseless-javascript-features","status":"publish","type":"post","link":"https:\/\/vfflogs.com\/index.php\/2023\/12\/28\/making-sense-of-senseless-javascript-features\/","title":{"rendered":"Making Sense Of \u201cSenseless\u201d JavaScript Features"},"content":{"rendered":"

Making Sense Of \u201cSenseless\u201d JavaScript Features<\/title><\/p>\n<article>\n<header>\n<h1>Making Sense Of \u201cSenseless\u201d JavaScript Features<\/h1>\n<address>Juan Diego Rodr\u00edguez<\/address>\n<p> 2023-12-28T10:00:00+00:00<br \/>\n 2023-12-29T10:05:55+00:00<br \/>\n <\/header>\n<p>Why does JavaScript have so many eccentricities!? Like, why does <code>0.2 + 0.1<\/code> equals <code>0.30000000000000004<\/code>? Or, why does <code>"" == false<\/code> evaluate to <code>true<\/code>?<\/p>\n<p>There are a lot of mind-boggling decisions in JavaScript that seem pointless; some are misunderstood, while others are direct missteps in the design. Regardless, it\u2019s worth knowing <em>what<\/em> these strange things are and <em>why<\/em> they are in the language. I\u2019ll share what I believe are some of the quirkiest things about JavaScript and make sense of them.<\/p>\n<h2 id=\"0-1-0-2-and-the-floating-point-format\"><code>0.1 + 0.2<\/code> And The Floating Point Format<\/h2>\n<p>Many of us have mocked JavaScript by writing <code>0.1 + 0.2<\/code> in the console and watching it resoundingly fail to get <code>0.3<\/code>, but rather a funny-looking <code>0.30000000000000004<\/code> value.<\/p>\n<p>What many developers might not know is that the weird result is not really JavaScript\u2019s fault! JavaScript is merely adhering to the <a href=\"https:\/\/ieeexplore.ieee.org\/document\/8766229\"><strong>IEEE Standard for Floating-Point Arithmetic<\/strong><\/a> that nearly every other computer and programming language uses to represent numbers.<\/p>\n<p>But what exactly is the Floating-Point Arithmetic?<\/p>\n<p>Computers have to represent numbers in all sizes, from the distance between planets and even between atoms. On paper, it\u2019s easy to write a massive number or a minuscule quantity without worrying about the size it will take. Computers don\u2019t have that luxury since they have to save all kinds of numbers in binary and a small space in memory.<\/p>\n<p>Take an 8-bit integer, for example. In binary, it can hold integers ranging from <code>0<\/code> to <code>255<\/code>.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/1-8-bit-integers-showing-0-255.jpg\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/1-8-bit-integers-showing-0-255.jpg\" alt=\"8-bit integers showing 0 and 255.\" \/><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n 8-bit integers showing 0 and 255. (<a href=\"https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/1-8-bit-integers-showing-0-255.jpg\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>The keyword here is <em>integers<\/em>. It can\u2019t represent any decimals between them. To fix this, we could add an imaginary decimal point somewhere along our 8-bit so the bits before the point are used to represent the integer part and the rest are used for the decimal part. Since the point is always in the same imaginary spot, it\u2019s called a <strong>fixed point decimal<\/strong>. But it comes with a great cost since the range is reduced from <strong><code>0<\/code> to <code>255<\/code><\/strong> to exactly <strong><code>0<\/code> to <code>15.9375<\/code><\/strong>.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/2-decimals-fixed-point.jpg\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/2-decimals-fixed-point.jpg\" alt=\"Decimals with a fixed point.\" \/><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Decimals with a fixed point. (<a href=\"https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/2-decimals-fixed-point.jpg\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>Having greater precision means sacrificing range, and vice versa. We also have to take into consideration that computers need to please a large number of users with different requirements. An engineer building a bridge doesn\u2019t worry too much if the measurements are off by just a little, say a hundredth of a centimeter. But, on the other hand, that same hundredth of a centimeter can end up costing much more for someone making a microchip. The precision that\u2019s needed is different, and the consequences of a mistake can vary.<\/p>\n<p>Another consideration is the size where numbers are stored in memory since storing long numbers in something like a megabyte isn\u2019t feasible.<\/p>\n<p>The <em>floating-point<\/em> format was born from this need to represent both large and small quantities with precision and efficiency. It does so in three parts:<\/p>\n<ol>\n<li>A single bit that represents whether or not the number is positive or negative (<code>0<\/code> for positive, <code>1<\/code> for negative).<\/li>\n<li>A <a href=\"https:\/\/mathworld.wolfram.com\/Significand.html\">significand<\/a> or <a href=\"https:\/\/mathworld.wolfram.com\/Mantissa.html\">mantissa<\/a> that contains the number\u2019s digits.<\/li>\n<li>An <strong>exponent<\/strong> specifies where the decimal (or binary) point is placed relative to the beginning of the mantissa, similar to how scientific notation works. Consequently, the point can move around to any position, hence the <em>floating<\/em> point.<\/li>\n<\/ol>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/3-decimals-floating-point.jpg\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/3-decimals-floating-point.jpg\" alt=\"Decimals with a floating point.\" \/><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Decimals with a floating point. (<a href=\"https:\/\/files.smashing.media\/articles\/making-sense-of-senseless-javascript-features\/3-decimals-floating-point.jpg\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>An 8-bit floating-point format can represent numbers between <code>0.0078<\/code> to <code>480<\/code> (and its negatives), but notice that the floating-point representation can\u2019t represent all of the numbers in that range. It\u2019s impossible since 8 bits can represent only 256 distinct values. Inevitably, many numbers cannot be accurately represented. There are <em>gaps<\/em> along the range. Computers, of course, work with more bits to increase accuracy and range, commonly with 32-bits and 64-bits, but it\u2019s impossible to represent all numbers accurately, a small price to pay if we consider the range we gain and the memory we save.<\/p>\n<p>The exact dynamics are far more complex, but for now, we only have to understand that while this format allows us to express numbers in a large range, it loses precision (the gaps between representable values get bigger) when they become too big. For example, JavaScript numbers are presented in a double-precision floating-point format, i.e., each number is represented in 64 bits in memory, leaving 53 bits to represent the mantissa. That means JavaScript can only safely represent integers between –(2<sup>53<\/sup> — 1) and 2<sup>53<\/sup> — 1 without losing precision. Beyond that, the arithmetic stops making sense. That\u2019s why we have the <code>Number.MAX_SAFE_INTEGER<\/code> static data property to represent the maximum safe integer in JavaScript, which is (2<sup>53<\/sup> — 1) or <code>9007199254740991<\/code>.<\/p>\n<p>But <code>0.3<\/code> is obviously below the <code>MAX_SAFE_INTEGER<\/code> threshold, so why can\u2019t we get it when adding <code>0.1<\/code> and <code>0.2<\/code>? The floating-point format struggles with some fractional numbers. It isn\u2019t a problem with the floating-point format, but it certainly is across any number system.<\/p>\n<p>To see this, let\u2019s represent one-third (<sup>1<\/sup>⁄<sub>3<\/sub>) in base-10.<\/p>\n<pre><code class=\"language-bash\">0.3\n<\/code><\/pre>\n<pre><code class=\"language-bash\">0.33\n<\/code><\/pre>\n<pre><code class=\"language-bash\">0.3333333 [...]\n<\/code><\/pre>\n<p>No matter how many digits we try to write, the result will never be <em>exactly<\/em> one-third. In the same way, we cannot accurately represent some fractional numbers in base-2 or binary. Take, for example, <code>0.2<\/code>. We can write it with no problem in base-10, but if we try to write it in binary we get a recurring <code>1001<\/code> at the end that repeats infinitely.<\/p>\n<pre><code class=\"language-bash\">0.001 1001 1001 1001 1001 1001 10 [...]\n<\/code><\/pre>\n<p>We obviously can\u2019t have an infinitely large number, so at some point, the mantissa has to be truncated, making it impossible not to lose precision in the process. If we try to convert <code>0.2<\/code> from double-precision floating-point back to base-10, we will see the actual value saved in memory:<\/p>\n<pre><code class=\"language-bash\">0.200000000000000011102230246251565404236316680908203125\n<\/code><\/pre>\n<p>It isn\u2019t 0.2! We cannot represent an awful lot of fractional values — not only in JavaScript but in almost all computers. So why does running <code>0.2 + 0.2<\/code> correctly compute <code>0.4<\/code>? In this case, the imprecision is so small that it gets rounded by Javascript (at the 16<sup>th<\/sup> decimal), but sometimes the imprecision is enough to escape the rounding mechanism, as is the case with <code>0.2 + 0.1<\/code>. We can see what\u2019s happening under the hood if we try to sum the actual values of <code>0.1<\/code> and <code>0.2<\/code>.<\/p>\n<p>This is the actual value saved when writing <code>0.1<\/code>:<\/p>\n<pre><code class=\"language-bash\">0.1000000000000000055511151231257827021181583404541015625\n<\/code><\/pre>\n<p>If we manually sum up the actual values of <code>0.1<\/code> and <code>0.2<\/code>, we will see the culprit:<\/p>\n<pre><code class=\"language-bash\">0.3000000000000000444089209850062616169452667236328125\n<\/code><\/pre>\n<p>That value is rounded to <code>0.30000000000000004<\/code>. You can check the real values saved at <a href=\"https:\/\/float.exposed\/0x3fb999999999999a\">float.exposed<\/a>.<\/p>\n<p>Floating-point has its known flaws, but its positives outweigh them, and it\u2019s standard around the world. In that sense, it\u2019s actually a relief when all modern systems will give us the same <code>0.30000000000000004<\/code> result across architectures. It might not be the result you expect, but it\u2019s a result you can predict.<\/p>\n<div data-audience=\"non-subscriber\" data-remove=\"true\" class=\"feature-panel-container\">\n<aside class=\"feature-panel\">\n<div class=\"feature-panel-left-col\">\n<div class=\"feature-panel-description\">\n<p>Roll up your sleeves and <strong>boost your UX skills<\/strong>: with <strong><a data-instant href=\"https:\/\/smart-interface-design-patterns.com\/\">Smart Interface Design Patterns<\/a><\/strong> \ud83c\udf63, a 9h-video library by Vitaly Friedman. <strong>100s of real-life examples<\/strong> and live UX training. <a href=\"https:\/\/www.youtube.com\/watch?v=aSP5oR9g-ss&ab_channel=SmashingMagazine\">Free preview<\/a>.<\/p>\n<p><a data-instant href=\"https:\/\/smart-interface-design-patterns.com\/\" class=\"btn btn--green btn--large\">Jump to table of contents \u21ac<\/a><\/div>\n<\/div>\n<div class=\"feature-panel-right-col\"><a data-instant href=\"https:\/\/smart-interface-design-patterns.com\/\" class=\"feature-panel-image-link\"><\/p>\n<div class=\"feature-panel-image\">\n<img loading=\"lazy\" class=\"feature-panel-image-img\" src=\"https:\/\/archive.smashing.media\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/8c98e7f9-8e62-4c43-b833-fc6bf9fea0a9\/video-course-smart-interface-design-patterns-vitaly-friedman.jpg\" alt=\"Feature Panel\" width=\"690\" height=\"790\" \/><\/p>\n<\/div>\n<p><\/a>\n<\/div>\n<\/aside>\n<\/div>\n<h2 id=\"type-coercion\">Type Coercion<\/h2>\n<p>JavaScript is a dynamically typed language, meaning we don\u2019t have to declare a variable\u2019s type, and it can be changed later in the code.<\/p>\n<blockquote class=\"pull-quote\">\n<p>\n <a class=\"pull-quote__link\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=%0aI%20find%20dynamically%20typed%20languages%20liberating%20since%20we%20can%20focus%20more%20on%20the%20substance%20of%20the%20code.%0a&url=https:\/\/smashingmagazine.com%2f2023%2f12%2fmaking-sense-of-senseless-javascript-features%2f\"><\/p>\n<p>I find dynamically typed languages liberating since we can focus more on the substance of the code.<\/p>\n<p> <\/a>\n <\/p>\n<div class=\"pull-quote__quotation\">\n<div class=\"pull-quote__bg\">\n <span class=\"pull-quote__symbol\">\u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\n<p>The issue comes from being weakly typed since there are many occasions where the language will try to do an implicit conversion between different types, e.g., from strings to numbers or <em>falsy<\/em> and <em>truthy<\/em> values. This is specifically true when using the equality ( <code>==<\/code>) and plus sign (<code>+<\/code>) operators. The rules for type coercion are intricate, hard to remember, and even incorrect in certain situations. It\u2019s better to avoid using <code>==<\/code> and always prefer the strict equality operator (<code>===<\/code>).<\/p>\n<p>For example, JavaScript will coerce a string to a number when compared with another number:<\/p>\n<pre><code class=\"language-javascript\">console.log(\"2\" == 2); \/\/ true\n<\/code><\/pre>\n<p>The inverse applies to the plus sign operator (<code>+<\/code>). It will try to coerce a number into a string when possible:<\/p>\n<pre><code class=\"language-javascript\">console.log(2 + \"2\"); \/\/ \"22\"\n<\/code><\/pre>\n<p>That\u2019s why we should only use the plus sign operator (<code>+<\/code>) if we are sure that the values are numbers. When concatenating strings, it\u2019s better to use the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/String\/concat\"><code>concat()<\/code><\/a> method or <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Template_literals\">template literals<\/a>.<\/p>\n<p>The reason such coercions are in the language is actually absurd. When JavaScript creator Brendan Eich was asked what <a href=\"https:\/\/thenewstack.io\/brendan-eich-on-creating-javascript-in-10-days-and-what-hed-do-differently-today#:~:text=notorious\">he would have done differently<\/a> in JavaScript\u2019s design, his answer was to be more meticulous in the implementations early users of the language wanted:<\/p>\n<blockquote><p>\u201cI would have avoided some of the compromises that I made when I first got early adopters, and they said, \u201cCan you change this?\u201d<\/p>\n<p>— Brendan Eich<\/p><\/blockquote>\n<p>The most glaring example is the reason why we have two equality operators, <code>==<\/code> and <code>===<\/code>. When an early JavaScript user prompted his need to compare a number to a string without having to change his code to make a conversion, Brendan added the loose equality operator to satisfy those needs.<\/p>\n<p>There are a lot of other rules governing the loose equality operator (and other statements checking for a condition) that make JavaScript developers scratch their heads. They are complex, tedious, and senseless, so we should avoid the loose equality operator (<code>==<\/code>) at all costs and replace it with its strict homonym (<code>===<\/code>).<\/p>\n<p>Why do we have two equality operators in the first place? A lot of factors, but we can point a finger at Guy L. Steele, co-creator of the Scheme programming language. He assured Eich that we could always add another equality operator since there were dialects with five distinct equality operators in the Lisp language! This mentality is dangerous, and nowadays, all features have to be rigorously analyzed because we can always add new features, but once they are in the language, they cannot be removed.<\/p>\n<div class=\"sponsors__lead-place\"><\/div>\n<h2 id=\"automatic-semicolon-insertion\">Automatic Semicolon Insertion<\/h2>\n<p>When writing code in JavaScript, a semicolon (<code>;<\/code>) is required at the end of some statements, including:<\/p>\n<ul>\n<li><code>var<\/code>, <code>let<\/code>, <code>const<\/code>;<\/li>\n<li>Expression statements;<\/li>\n<li><code>do...while<\/code>;<\/li>\n<li><code>continue<\/code>, <code>break<\/code>, <code>return<\/code>, <code>throw<\/code>;<\/li>\n<li><code>debugger<\/code>;<\/li>\n<li>Class field declarations (public or private);<\/li>\n<li><code>import<\/code>, <code>export<\/code>.<\/li>\n<\/ul>\n<p>That said, we don\u2019t necessarily have to insert a semicolon every time since JavaScript can automatically insert semicolons in a process unsurprisingly known as <strong>Automatic Semicolon Insertion<\/strong> (ASI). It was intended to make coding easier for beginners who didn\u2019t know where a semicolon was needed, but it isn\u2019t a reliable feature, and we should stick to explicitly typing where a semicolon goes. Linters and formatters add a semicolon where ASI would, but they aren\u2019t completely reliable either.<\/p>\n<p>ASI can make some code work, but most of the time it doesn\u2019t. Take the following code:<\/p>\n<pre><code class=\"language-javascript\">const a = 1\n(1).toString()\n\nconst b = 1\n[1, 2, 3].forEach(console.log)\n<\/code><\/pre>\n<p>You can probably see where the semicolons go, and if we formatted it correctly, it would end up as:<\/p>\n<pre><code class=\"language-javascript\">const a = 1;\n\n(1).toString();\n\nconst b = 1;\n\n[(1, 2, 3)].forEach(console.log);\n<\/code><\/pre>\n<p>But if we feed the prior code directly to JavaScript, all kinds of exceptions would be thrown since it would be the same as writing this:<\/p>\n<pre><code class=\"language-javascript\">const a = 1(1).toString();\n\nconst b = (1)[(1, 2, 3)].forEach(console.log);\n<\/code><\/pre>\n<p>In conclusion, know your semicolons.<\/p>\n<h2 id=\"why-so-many-bottom-values\">Why So Many Bottom Values?<\/h2>\n<p>The term \u201cbottom\u201d is often used to represent a value that does not exist or is undefined. But why do we have two kinds of bottom values in JavaScript?<\/p>\n<p>Everything in JavaScript can be considered an object, except the two bottom values <code>null<\/code> and <code>undefined<\/code> (despite <code>typeof null<\/code> returning <code>object<\/code>). Attempting to get a property value from them raises an exception.<\/p>\n<p>Note that, strictly speaking, <strong>all primitive values aren\u2019t objects<\/strong>. But only <code>null<\/code> and <code>undefined<\/code> aren\u2019t subjected to <a href=\"https:\/\/stackoverflow.com\/questions\/34067261\/is-boxing-coercion-in-javascript\"><em>boxing<\/em><\/a>.<\/p>\n<p>We can even think of <code>NaN<\/code> as a third bottom value that represents the absence of a number. The abundance of bottom values should be regarded as a design error. There isn\u2019t a straightforward reason that explains the existence of two bottom values, but we can see a difference in how JavaScript employs them.<\/p>\n<p><code>undefined<\/code> is the bottom value that JavaScript uses by default, so it\u2019s considered good practice to use it exclusively in your code. When we define a variable without an initial value, attempting to retrieve it assigns the <code>undefined<\/code> value. The same thing happens when we try to access a non-existing property from an object. To match JavaScript\u2019s behavior as closely as possible, use <code>undefined<\/code> to denote an existing property or variable that doesn\u2019t have a value.<\/p>\n<p>On the other hand, <code>null<\/code> is used to represent the absence of an object (hence, its <code>typeof<\/code> returns an <code>object<\/code> even though it isn\u2019t). However, this is considered a design blunder because <code>undefined<\/code> could fulfill its purposes as effectively. It\u2019s used by JavaScript to denote the end of a recursive data structure. More specifically, it\u2019s used in the prototype chain to denote its end. Most of the time, you can use <code>undefined<\/code> over <code>null<\/code>, but there are some occasions where only <code>null<\/code> can be used, as is the case with <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Object\/create\"><code>Object.create<\/code><\/a> in which we can only create an object without a prototype passing <code>null<\/code>; using <code>undefined<\/code> returns a <code>TypeError<\/code>.<\/p>\n<p><code>null<\/code> and <code>undefined<\/code> both suffer from the path problem. When trying to access a property from a bottom value — as if they were objects — exceptions are raised.<\/p>\n<pre><code class=\"language-javascript\">let user;\n\nlet userName = user.name; \/\/ Uncaught TypeError\n\nlet userNick = user.name.nick; \/\/ Uncaught TypeError\n<\/code><\/pre>\n<p>There is no way around this unless we check for each property value before trying to access the next one, either using the logical AND (<code>&&<\/code>) or optional chaining (<code>?<\/code>).<\/p>\n<pre><code class=\"language-javascript\">let user;\n\nlet userName = user?.name;\n\nlet userNick = user && user.name && user.name.nick;\n\nconsole.log(userName); \/\/ undefined\n\nconsole.log(userNick); \/\/ undefined\n<\/code><\/pre>\n<p>I said that <code>NaN<\/code> can be considered a bottom value, but it has its own confusing place in JavaScript since it represents numbers that aren\u2019t actual numbers, usually due to a failed string-to-number conversion (which is another reason to avoid it). <code>NaN<\/code> has its own shenanigans because it isn\u2019t equal to itself! To test if a value is <code>NaN<\/code> or not, use <code>Number.isNaN()<\/code>.<\/p>\n<p>We can check for all three bottom values with the following test:<\/p>\n<pre><code class=\"language-javascript\">function stringifyBottom(bottomValue) {\n if (bottomValue === undefined) {\n return \"undefined\";\n }\n\n if (bottomValue === null) {\n return \"null\";\n }\n\n if (Number.isNaN(bottomValue)) {\n return \"NaN\";\n }\n}\n<\/code><\/pre>\n<div class=\"sponsors__lead-place\"><\/div>\n<h2 id=\"increment-and-decrement\">Increment (<code>++<\/code>) And Decrement (<code>--<\/code>)<\/h2>\n<p>As developers, we tend to spend more time reading code rather than writing it. Whether we are reading documentation, reviewing someone else\u2019s work, or checking our own, <strong>code readability will increase our productivity over brevity<\/strong>. In other words, readability saves time in the long run.<\/p>\n<p>That\u2019s why I prefer using <code>+ 1<\/code> or <code>- 1<\/code> rather than the increment (<code>++<\/code>) and decrement (<code>--<\/code>) operators.<\/p>\n<p>It\u2019s illogical to have a different syntax exclusively for incrementing a value by one in addition to having a pre-increment form and a post-increment form, depending on where the operator is placed. It is very easy to get them reversed, and that can be difficult to debug. They shouldn\u2019t have a place in your code or even in the language as a whole when we consider where the increment operators come from.<\/p>\n<p>As we saw in a <a href=\"https:\/\/www.smashingmagazine.com\/2023\/12\/marketing-changed-oop-javascript\/\">previous article<\/a>, JavaScript syntax is heavily inspired by the C language, which uses pointer variables. Pointer variables were designed to store the memory addresses of other variables, enabling dynamic memory allocation and manipulation. The <code>++<\/code> and <code>--<\/code> operators were originally crafted for the specific purpose of advancing or stepping back through memory locations.<\/p>\n<p>Nowadays, pointer arithmetic has been proven harmful and can cause accidental access to memory locations beyond the intended boundaries of arrays or buffers, leading to memory errors, a notorious source of bugs and vulnerabilities. Regardless, the syntax made its way to JavaScript and remains there today.<\/p>\n<p>While the use of <code>++<\/code> and <code>--<\/code> remains a standard among developers, an argument for readability can be made. Opting for <code>+ 1<\/code> or <code>- 1<\/code> over <code>++<\/code> and <code>--<\/code> not only aligns with the principles of clarity and explicitness but also avoids having to deal with its pre-increment form and post-increment form.<\/p>\n<p>Overall, it isn\u2019t a life-or-death situation but a nice way to make your code more readable.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>JavaScript\u2019s seemingly senseless features often arise from historical decisions, compromises, and attempts to cater to all needs. Unfortunately, it\u2019s impossible to make everyone happy, and JavaScript is no exception.<\/p>\n<blockquote class=\"pull-quote\">\n<p>\n <a class=\"pull-quote__link\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=%0aJavaScript%20doesn%e2%80%99t%20have%20the%20responsibility%20to%20accommodate%20all%20developers,%20but%20each%20developer%20has%20the%20responsibility%20to%20understand%20the%20language%20and%20embrace%20its%20strengths%20while%20being%20mindful%20of%20its%20quirks.%0a&url=https:\/\/smashingmagazine.com%2f2023%2f12%2fmaking-sense-of-senseless-javascript-features%2f\"><\/p>\n<p>JavaScript doesn\u2019t have the responsibility to accommodate all developers, but each developer has the responsibility to understand the language and embrace its strengths while being mindful of its quirks.<\/p>\n<p> <\/a>\n <\/p>\n<div class=\"pull-quote__quotation\">\n<div class=\"pull-quote__bg\">\n <span class=\"pull-quote__symbol\">\u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\n<p>I hope you find it worth your while to keep learning more and more about JavaScript and its history to get a grasp of its misunderstood features and questionable decisions. Take its amazing prototypal nature, for example. It was obscured during development or blunders like the <code>this<\/code> keyword and its multipurpose behavior.<\/p>\n<p>Either way, I encourage every developer to research and learn more about the language. And if you\u2019re interested, I go a bit deeper into questionable areas of JavaScript\u2019s design in <a href=\"https:\/\/www.smashingmagazine.com\/2023\/12\/marketing-changed-oop-javascript\/\">another article published here on Smashing Magazine<\/a>!<\/p>\n<div class=\"signature\">\n <img src=\"https:\/\/www.smashingmagazine.com\/images\/logo\/logo--red.png\" alt=\"Smashing Editorial\" width=\"35\" height=\"46\" loading=\"lazy\" \/><br \/>\n <span>(gg, yk)<\/span>\n<\/div>\n<\/article>\n","protected":false},"excerpt":{"rendered":"<p>Making Sense Of \u201cSenseless\u201d JavaScript Features Making Sense Of \u201cSenseless\u201d JavaScript Features Juan Diego Rodr\u00edguez 2023-12-28T10:00:00+00:00 2023-12-29T10:05:55+00:00 Why ...<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/posts\/2849"}],"collection":[{"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/comments?post=2849"}],"version-history":[{"count":1,"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/posts\/2849\/revisions"}],"predecessor-version":[{"id":2850,"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/posts\/2849\/revisions\/2850"}],"wp:attachment":[{"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/media?parent=2849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/categories?post=2849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vfflogs.com\/index.php\/wp-json\/wp\/v2\/tags?post=2849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}