In JavaScript there are little technicalities that don’t quite make sense at first until you discover them. Now, everyone has their own list of JavaScript Gotchas, but things like “JavaScript is case sensitive” isn’t a real gotcha. To me, that is how it should be. It’s not a confusing trick. It’s just technical in that way.
A true “gotcha” to me is when 1 == 1
and 1 == '1'
is true, but [] == []
is not true. Albeit, this is one of the more simple “gotchas”, it still doesn’t immediately appear intuitive until you delve into the “why”.
In this guide, we’ll go through some of the common gotchas that you might find in a JavaScript interview. Interviewers probably won’t directly ask these questions, but they might ask you something relative to them or to do a problem involving them.
This is one of the most basic gotchas - at first the var
and let
keywords seemed so similar to me, I couldn’t tell there was any difference. But, here is a common way to show the difference:
// let
for(let i=0; i<10; i++) {
//...
}
console.log(i) // Reference Error: i is not defined
// var
for(var j=0; j<10; j++) {
//...
}
console.log(j) // 10
One big difference is that let
is block-scoped - meaning it’s limited to whatever block it is defined in. In order for the console.log
to know what i
is, you would have to hoist the i
out of the for
loop. That’s exactly what var
does behind the scenes. The var
keyword is function-scoped, as in, only limited by the parent function. And is automatically hoisted outside the block it is declared in.
1 + 1; // 2, obviously
1 + "1"; // "11"
As you can see, JavaScript converts numbers to strings. Or does it?
1 - "1"; // 0 (number)
1 * "1"; // 1 (number)
1 / "1"; // 1 (number)
"1" * "1"; // 1 (yep, still a number)
No, in fact JavaScript converts strings to numbers in most cases. In the case of the +
operator, it’s concatenated instead of added. Concatenated, like strings: "your" + "name" // "your name"
.
NaN
stands for “not a number”. It’s one of the more confusing ("number"s?) to deal with in JavaScript. For instance:
NaN === NaN; // false
NaN == NaN; // false as well
typeof NaN; // number
"" == NaN; // false
In fact anything equal to “NaN” is false, event though there are plenty of things that are “not a number”. That’s why instead you must use isNaN()
. But even that can be confusing:
isNaN("string"); // true - what we would expect, as a string is not a number
isNaN(123); // false - also expected
// false means it's a number, right?
isNaN(""); // false - hmm...
isNaN("45"); // false - this is a string, I thought
isNaN([]); // false - wait so an empty array is a number?
isNaN([1, 2]); // true
isNaN({}); // true
isNaN(() => {}); // true
You may already be familiar with the differences between ==
and ===
. ==
checks only the value, while ===
includes type checking. That’s why 1 === "1"
is false, but 1 == "1"
is true. But, did you know this is true: null == undefined
. But of course, this is loose checking with the ==
.
There’s also the !=
which would be saying “not equal”. This is true: null !== undefined
, but this is false null != undefined
. Following? Basically, the first one is saying, “null is not exactly equal to undefined”, yet the second says, “null isn’t not loosely equal to undefined” (double negative, means they are loosely equal).
But let’s look at more comparisons that get even more convoluted. These all checkout as true:
false == '0' // true
0 == false // true
'' == 0 // true
false == '' // true
[] == '' // true, but we'll get to this
'1' == true // true
1 == true // true
'false' == true // true
These are the confusing comparison checks, but they aren’t technically truthy vs. falsy. They are just value checks, because remember []==[]
results is false and yet, “[]” is a truthy value. The way to check for truthy vs falsy, is putting things in an if
block. For instance:
if ("") {
console.log(true);
} else {
console.log(false);
}
// logs false
//But look at this
if ([]) {
console.log(true);
}
// logs true - an empty array is still truthy
if ([] == "") {
console.log(true);
}
// logs true - but look at the first one - it logged false
An empty object, {}
, also logs true. JavaScript is quite interesting when it comes to equality and types, but I suggest using the triple equals ===
or !==
for your comparisons.
Now, the last example is a good picture of a key distinction. The loose equality checks, checks for value, not necessarily falsy/truthy. if
blocks check for falsy/truthy. See, in JavaScript this is true: [] == false
. But as we saw above, an if
block checks an empty array as truthy. Obviously, if(false)
will not go anywhere.
I’ve noticed that if I forgot to add a semicolon to end one line of code, it doesn’t give me an error. Behind the scenes Automatic Semicolon Insertion inserts the missing semicolon, which is okay, but could create a bad habit. Some statements need the semicolon or JavaScript might not know they have ended, while others, as we will see, haven’t ended at all, but JavaScript thought it had.
function increment(num) {
return
++num
}
console.log(increment(3))
Now that’s not the best example in the world, but it might surprise you that it returns undefined
. That’s because a semicolon is secretly inserted at the end of “return” and the next line of code is never reached. A little bit like this:
function increment(num) {
return;
++num;
}
console.log(increment(3));
Finally, JavaScript has this weird behavior of creating global variables out of thin air. This circles back to our first gotcha dealing with let
vs var
keywords.
Remember we said that let
is block-scoped, while var
is function-scoped? What then is this?
for(i = 0; i < 10; i++) {
// ...
}
console.log(i); // 10
Notice what we did? There is no definition to the “i” variable: i=0
. What’s the result? A global variable was created. This is a dangerous thing, because now our i
variable is global.
This is also true in any function: function someFn() { someVar = 0; }
. The someVar
here becomes a global variable and it’s akin to saying window.var = 0
.
JavaScript has some tricky stuff to navigate and the truth is interviewers will quiz you on them, even if you wouldn’t practically ever see them in a real-life scenario. But, what are you to do?
The good news is, there is plenty of documentation and video-teachings out there to show you these things. I would recommend doing a search for things like “JavaScript tough interview questions” or “JavaScript tricky questions”. And even if you don’t get them in an interview, at least you know them for future problems if they ever come up. Plus, you can trick your friends with them as well!
Best of luck and when in doubt, just remember these are things all developers face - you aren’t alone!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!