Artigo original: https://www.freecodecamp.org/news/cannot-read-property-split-of-undefined-error/

Se você já usou o método split do JavaScript, há uma boa probabilidade de você já ter encontrado este erro: TypeError: Cannot read property 'split' of undefined.

Existem algumas razões pelas quais você poderia receber esse erro. Provavelmente, é apenas um entendimento básico e incorreto de como o método split funciona e de como percorrer elementos dos arrays.

Por exemplo, se você tentar enviar o código abaixo para o desafio Encontrar a palavra mais longa em uma string:

function findLongestWord(str) { 
  for(let i = 0; i < str.length; i++) {
    const array = str.split(" ");
    array[i].split("");
  }
}

findLongestWord("The quick brown fox jumped over the lazy dog");

Você receberá o erro TypeError: Cannot read property 'split' of undefined.

O método split

Quando split é chamado em uma string, ele divide a string em substrings com base no separador passado a ele como um argumento. Se uma string vazia é passada como argumento, split trata cada caractere como uma substring. Ele, então, retorna um array contendo as substrings:

const testStr1 = "Test test 1 2";
const testStr2 = "cupcake pancake";
const testStr3 = "First,Second,Third";

testStr1.split(" "); // [ 'Test', 'test', '1', '2' ]
testStr2.split(""); // [ 'c', 'u', 'p', 'c', 'a', 'k', 'e', ' ', 'p', 'a', 'n', 'c', 'a', 'k', 'e' ]
testStr3.split(","); // [ 'First', 'Second', 'Third' ]

Confira a MDN para ver mais detalhes sobre o método split.

O problema explicado com exemplos

Saber o que é retornado pelo método split e quantas substrings você pode esperar é a chave para resolver este desafio.

Vamos olhar novamente o código acima e ver o motivo de ele não estar funcionando conforme o esperado:

function findLongestWord(str) { 
  for(let i = 0; i < str.length; i++) {
    const array = str.split(" ");
    array[i].split("");
  }
}

findLongestWord("The quick brown fox jumped over the lazy dog");

Dividir str em um array assim (const array = str.split(" ");) funciona conforme o esperado e retorna [ 'The',   'quick',   'brown',   'fox',   'jumped',   'over',   'the',   'lazy',   'dog' ].

Vejamos mais de perto, porém, o laço for. Em vez de usar o tamanho do array como condição para as iterações i, str.length é usado em seu lugar.

str é "The quick brown fox jumped over the lazy dog". Se você usar console.log em str.length, verá que o resultado é 44.

A última instrução do corpo do laço for é o que está causando o erro: array[i].split("");. O tamanho do array é 9. Assim, i passaria rapidamente do tamanho máximo do array:

function findLongestWord(str) { 
  for(let i = 0; i < str.length; i++) {
    const array = str.split(" ");
    console.log(array[i]);
    // array[0]: "The"
    // array[1]: "quick"
    // array[2]: "brown"
    // ...
    // array[9]: "dog"
    // array[10]: undefined
    // array[11]: undefined
  }
}

findLongestWord("The quick brown fox jumped over the lazy dog");

Chamar array[i].split(""); para dividir cada string em substrings de caracteres é uma abordagem válida, mas lançará um erro TypeError: Cannot read property 'split' of undefined quando o que for passado ao método for um undefined.

Como resolver o desafio Encontrar a palavra mais longa em uma string com split

Vamos examinar rapidamente o pseudocódigo para ver como resolver esse problema:

  1. Dividir str em um array de palavras individuais
  2. Criar uma variável para acompanhar o tamanho da palavra mais longa
  3. Percorrer o array de palavras e comparar o tamanho de cada palavra à variável mencionada acima
  4. Se o tamanho da palavra atual for maior do que aquela armazenada na variável, substitua aquele valor pelo tamanho da palavra atual
  5. Quando o tamanho de cada palavra for comparado com a variável do tamanho máximo de palavra, retorne aquele número por meio da função

Primeiro, dividimos str em um array de palavras individuais:

function findLongestWordLength(str) {
  const array = str.split(" ");
}

Criamos uma variável para acompanhar o tamanho da palavra mais longa e a definimos como zero:

function findLongestWordLength(str) {
  const array = str.split(" ");
  let maxWordLength = 0;
}

Agora que o valor do array é ['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog'], podemos usar array.length em seu laço for:

function findLongestWordLength(str) {
  const array = str.split(" ");
  let maxWordLength = 0;
  
  for (let i = 0; i < array.length; i++) {
    
  }
}

Vamos percorrer o array de palavras e verificar o tamanho de cada palavra. Lembre-se de que as strings também têm um método length que você pode chamar para obter facilmente o tamanho de uma string:

function findLongestWordLength(str) {
  const array = str.split(" ");
  let maxLength = 0;
  
  for (let i = 0; i < array.length; i++) {
    array[i].length;
  }
}

Usamos uma instrução if para verificar se o tamanho da palavra atual (array[i].length) é maior que maxLength. Se for, substituímos o valor de maxLength por array[i].length:

function findLongestWordLength(str) {
  const array = str.split(" ");
  let maxLength = 0;
  
  for (let i = 0; i < array.length; i++) {
    if (array[i].length > maxLength) {
      maxLength = array[i].length;
    }
  }
}

Por fim, retornamos maxLength ao final da função, após o laço for:

function findLongestWordLength(str) {
  const array = str.split(" ");
  let maxLength = 0;
  
  for (let i = 0; i < array.length; i++) {
    if (array[i].length > maxLength) {
      maxLength = array[i].length;
    }
  }
    
  return maxLength;
}