
Unravelling JavaScript: Commonly Misunderstood Methods and Features

JavaScript is not just a programming language; it's a canvas of possibilities, rich with features that make it both incredibly powerful and ‑ at times ‑ totally bewildering. It is common to find even seasoned developers tripping up over some of it's more quirky idiosyncrasies.
Today, I'm going to explore some of the most commonly misunderstood aspects of JavaScript and ‑ in an attempt to find some more relevant and interesting content for my blog and website visitors ‑ over the coming weeks and months, I'll put together a short article to focus on each in more detail.
For now, here's a list of some of the aspects of JavaScript that are most commonly misunderstood or have gotchas that catch out even the most experienced of developers:
Array.prototype.sort()
There's more than meets the eye with sort(). Have you ever tried to sort an array of numbers and ended up with 10 before 2? That's sort() in action, treating elements like strings.
I go into more detail on understanding Array.prototype.sort() here, and into even deeper detail on how you can use sort() to sort arrays of objects (like sorting products by prices) here.
Array.prototype.slice()
Using slice() silently duplicates sections of your array without altering the original. It is really common to see this mistaken with its more invasive counterpart, splice(), which behaves quite, quite differently...
I talk about using slice() in detail here.
Array.prototype.splice()
splice() is a bit of a multitool for arrays, capable of adding, removing, and replacing elements. Its versatility can be daunting and easily misunderstood, making it prone to misuse.
Read more about manipulating arrays with splice() here. I go into even more detail comparing slice() against splice() in my article here.
String.prototype.substring()
Extracting parts of a string should be simple, and substring() is just the tool for the job. It extracts characters from a string (just as you'd expect), but unlike its relative slice(), it has some confusing peculiarities when it comes to dealing with negative or out‑of‑order arguments.
String.prototype.substr()
Although substr() has been depreciated for quite some time (and in fact never made it into the JavaScript core specification), it still crops up on legacy codebases, and gets introduced anew by developers confusing it with substring(). Despite being virtually identical on the surface, substr uses length for extraction instead of the ending index, which makes it just dissimilar enough to cause confusion.
I talk about substring() and substr(), comparing the two in my article here.
String.prototype.split()
split() should be simple: give it a string and should return that same string in an array, broken down based on a predefined delimiter. However, understanding how different delimiters, or their absence, affect the output makes it more complicated than you might expect.
I've written an article all about manipulating string with split() here.
Math.random()
I've written about Math.random() before, and how ‑ actually ‑ you cannot create a truly random value using maths. Nevertheless, Math.random() is a pseudo‑random number generator that can mislead those expecting numbers outside of the 0‑to‑1 range.
parseInt()
Turning strings into integers with parseInt() can lead to some unusual and unexpected results if you ignore the radix. How it behaves with unexpected characters in the string can also result in hard‑to‑find bugs.
I've written about parseInt and the importance of understanding radix here.
isNaN()
The isNaN() function checks if a value is NaN ("Not a Number"), but it can return true for unexpected inputs, making it unreliable without understanding its coercion rules. I go into this in much more detail in a previous article here.
typeof
It may seem like typeof is a straightforward gatekeeper for type checking but can often output types that aren't accurate, particularly when it comes to arrays and null.
I have written about typeof, how it can be used and where it becomes more limited here.
instanceof
instanceof checks the prototype chain for a constructor but can quickly lead to false negatives, especially when dealing with multiple contexts, such as different iframes or realms.
You can read about instanceof and it's uses in detail in my article here.
null and undefined
Both null and undefined represent "no value", but they have different meanings and uses. They are not interchangeable, especially in comparisons.
This is something I've written about before.
== and ===
The equality (==) and strict equality (===) operators are similar at a glance, but understanding their coercion rules is vital to prevent unexpected type conversions. I've written about the differences between these equality operators and their uses before.
Object.prototype.hasOwnProperty()
hasOwnProperty() checks for a property's existence directly on an object, not on its prototype chain. This distinction is easy to overlook and can lead to incorrect assumptions about an object's properties.
Read a brief overview of hasOwnProperty in my article here.
Function.prototype.apply()
apply() calls a function with a given this and arguments provided as an array. It can be intricate to master, especially when dealing with the arguments array‑like object.
I go into detail about .apply() in my article here.
Function.prototype.bind()
Like apply(), bind() creates a new function with a set this and arguments. It can tie a function's this value and arguments for later use. This can sometimes be conflated with apply() and call(), which are immediate invocations.
You can read about .bind() in my article here.
setTimeout()
Any JavaScript developer should know, setTimeout() schedules code to run after a defined delay. However, its timing can be imprecise due to JavaScript's single‑threaded nature and event loop.
I have written about using setTimeout and the potential issues with timing accuracy here.
setInterval()
On a similar vein to setTimeout(), setInterval() is a handy way to run code at regular intervals, however, it can quickly result in queued calls if its callbacks take longer than the interval time.
Read more about setInterval in my article here.
Object.defineProperty()
defineProperty() configures properties with fine granularity, including descriptors like writable and enumerable. However, the complexity of these attributes often leads to misuse.
I talk about harnessing this powerful JavaScript method here.
Promise.prototype.then()
The then() method is the backbone of promise chaining, yet it is often misunderstood because it is used to handle the success or failure of a promise, whilst it returns a new promise that can ‑ itself ‑ be chained to other promises. It can get very confusing.
I have written about leveraging then() in modern JavaScript here.
Related Articles

The will‑change Property in CSS. The

Check If Today is Between Two Dates in JavaScript. Check If Today is Between Two Dates in JavaScript

Throttling Scroll Events in JavaScript. Throttling Scroll Events in JavaScript

Finding the Difference Between Two Strings in JavaScript. Finding the Difference Between Two Strings in JavaScript

Sort the Keys of an Object with JavaScript. Sort the Keys of an Object with JavaScript

Mutation vs. Immutability in JavaScript Arrays and Objects. Mutation vs. Immutability in JavaScript Arrays and Objects

The End of Internet Explorer. The End of Internet Explorer

Converting Between Camel, Snake, and Kebab Case in JavaScript. Converting Between Camel, Snake, and Kebab Case in JavaScript

A Brief Look at JavaScript’s Temporal Dates and Times API. A Brief Look at JavaScript's
TemporalDates and Times API
How to Use grid in CSS. How to Use
gridin CSS
Tagged Template Literals in JavaScript. Tagged Template Literals in JavaScript

Check If Your Site is Running on localhost. Check If Your Site is Running on
localhost