Tutorial

JavaScript Interview Questions: Common Gotchas

JavaScript

While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

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.

var vs. let

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.

Addition vs Concatenation

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 Gotchas

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

Equality / Truthy vs Falsy

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.

Automatic Semicolon Insertion

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));

Global Variables

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.

Conclusion

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!

0 Comments

Creative Commons License