You are not a Senior Front-end Developer if you don’t know JavaScript

Table of Contents

Tl;dr
Learn the fundamentals of JavaScript, even if you’ve been working with React for years. There’s a good chance you’re missing concepts that could make your life easier and expand your skill set.

Over the past three years, I’ve led engineering teams and interviewed more than 100 Front-end engineers.

I typically conduct a code-pairing session to assess candidates’ foundational knowledge, sharpness, and collaboration skills.

What’s surprising, even disappointing, is how many front-end engineers who call themselves “Seniors” 👴 lack a basic understanding of arrays, loops, and closures.

As a React developer myself, I understand how easy it is to start learning web development with React tutorials and miss the fundamentals of JavaScript (or even HTML/CSS).

The Code Pairing Problem

Below is a simplified version of the problem I usually give to the candidates during the code-pairing session:

// You have a 2D array with rows of 3 items containing "X" or "O".
// If a row contains three "X"s, return "X". 
// If it contains three "O"s, return "O".
// Otherwise, return `false`.
// Check only horizontally.
const input = [
  ["X", "O", "X"],
  ["O", "O", "O"],
  ["O", "O", "X"]
];

function solution(board) {
  // ... solution
}

solution(input); // In this case, returns "O"

Common Issues

Issue #1: Closures

A common problem among developers who start with React without solid JavaScript experience is a lack of understanding of closures.

function solution(board) {
  // 🚩 Red flag #1
  // The return statement is inside the `forEach` closure,
  // so it's effectively not used.
  board.forEach((row) => {
    const hasWinner =
      board[row].every((item) => item === "X") ||
      board[row].every((item) => item === "O");

    if (hasWinner) return board[row][0];
  });
  return false;
}

This gets me always to a weird position, as the internal logic with Array.every is correct, but I need to explain them why exactly this does not work, and what are closures.

Issue #2: Array Methods and Their Outputs

When working with React, developers often ignore what Array.map actually does. The usual React work is always something along the lines:

<div>
  {[1, 2, 3, 4, 5].map((i) => (
    <p>{i}</p>
  ))}
</div>

But with code, we assume we are returning a list of <p> elements. In reality, .map generates a new array containing those JSX elements.

I’ve lost count of how often I’ve encountered this misunderstanding during pair programming.

function solution(board) {
  let found = false;
  // 🚩 Red flag #2
  // Lack of awareness that `.map` returns a new array,
  // which is unnecessary in this context.
  board.map((row) => {
    const hasWinner =
      board[row].every((item) => item === "X") ||
      board[row].every((item) => item === "O");

    if (hasWinner) found = board[row][0];
  });

  return found;
}

In real-world, this happens almost always with the lack of knowledge about closures (see issue #1).

Issue #3: Understanding Basic Loops

This is perhaps the most disheartening. Loops are fundamental to programming, and being unable to write a simple for loop to iterate over an array is not a good sign.

The fact that many many React devs I interviewed do not know how to convert a .map/.forEach loop to a for loop, just to maintain the same lexical environment is just sad 🥲

Possible Solutions

Here are three potential solutions to the problem, though others exist:

Solution 1: Array.every

This solution is straightforward and demonstrates knowledge of array methods like Array.every.

// Solution #1
function solution(board) {
  for (let i = 0; i < board.length; i++) {
    const hasWinner =
      board[i].every((item) => item === "X") ||
      board[i].every((item) => item === "O");
    if (hasWinner) return board[i][0];
  }

  return false;
}

Solution 2: Set

This approach shows familiarity with Set, which is useful in many situations, like duplicate removal etc.

// Solution #2
function solution(board) {
  for (let i = 0; i < board.length; i++) {
    const uniqueItems = new Set(board[i]);
    const hasWinner = uniqueItems.size === 1 && !uniqueItems.has("");
    if (hasWinner) return board[i][0];
  }

  return false;
}

Solution 3: Basic for.. loop

This is the most performant solution, although I still appreciate when candidates know how to use array methods and can justify choosing a more efficient approach.

Benchmarks on PerfLink confirm the performance of this solution.

// Solution #3
function solution(board) {
  for (let i = 0; i < board.length; i++) {
    let found = true;
    let element = board[i][0];

    for (let j = 1; j < board[i].length; j++) {
      if (board[i][j] !== element) {
        found = false;
        break;
      }
    }

    if (found) return element;
  }

  return false;
}

Conclusion

In the fast-paced world of front-end development, it’s easy to get swept up in the latest frameworks and libraries while neglecting core programming skills.

But as this post illustrates, true mastery requires more than just surface-level familiarity with frameworks like React. It demands a solid grasp of JavaScript fundamentals—closures, array methods, and basic loops, to name a few. If you aspire to be a senior developer, make time to revisit the basics. Understanding JavaScript’s core concepts will not only elevate your coding skills but also enhance your ability to debug, optimize, and innovate by creating your own tools.


comments powered by Disqus