Что означает ошибка: TypeError: ‘undefined’ is not an object

Ситу­а­ция: вы пише­те скрипт, в кото­ром вам нуж­но выяс­нить рас­сто­я­ние от вер­ха экра­на до нача­ла нуж­но­го эле­мен­та. У это­го эле­мен­та есть класс .entry-content, и вы исполь­зу­е­те jQuery, что­бы досту­чать­ся до него:

// …
var dh;
dh = $('.entry_content').offset().top;

После запус­ка скрип­та бра­у­зер выда­ёт ошиб­ку:

❌ TypeError: ‘undefined’ is not an object

Стран­но, но вы точ­но зна­е­те, что таким спо­со­бом мож­но искать эле­мент по его клас­су. Более того, точ­но такой же код рабо­та­ет тре­мя строч­ка­ми выше и без оши­бок.

Что это зна­чит: бра­у­зер при виде точ­ки пони­ма­ет, что перед ним — объ­ект, у кото­ро­го есть какие-то свой­ства. Эта ошиб­ка озна­ча­ет, что вы пыта­е­тесь обра­тить­ся к свой­ствам несу­ще­ству­ю­ще­го объ­ек­та.

Когда встре­ча­ет­ся: когда про­грам­мист дела­ет опе­чат­ки в име­ни объ­ек­та, непра­виль­но объ­яв­ля­ет его или начи­на­ет рабо­тать с чем-то, что точ­но не объ­ект.

В нашем при­ме­ре про­грам­мист непра­виль­но ука­зал имя раз­де­ла при вызо­ве, и вот что про­изо­шло:

  1. Бра­у­зер зна­ет, что на стра­ни­це есть эле­мент с клас­сом entry-content, кото­рый напи­сан через дефис.
  2. Про­грам­мист увлёк­ся и поста­вил знак под­чёр­ки­ва­ния вме­сто дефи­са.
  3. Скрипт попы­тал­ся най­ти этот класс, но не смог, поэто­му вер­нул зна­че­ние undefined.
  4. После это­го коман­да ста­ла выгля­деть так: dh = undefined.offset().top, но undefined.offset() — это не объ­ект, а что-то неопре­де­лён­ное, у кото­ро­го нет свой­ства top.
  5. Бра­у­зер выда­ёт ошиб­ку, что вообще-то это не объ­ект и рабо­тать с ним он не будет.

Что делать с ошибкой TypeError: ‘undefined’ is not an object

Эта ошиб­ка озна­ча­ет, что вы пыта­е­тесь исполь­зо­вать как объ­ект то, что им не явля­ет­ся. Что­бы испра­вить эту ошиб­ку, про­верь­те:

  • нет ли у вас опе­ча­ток в име­нах и назва­ни­ях (ско­рее все­го);
  • пра­виль­но ли вы опре­де­ли­ли нуж­ный объ­ект;
  • в jQuery нуж­но будет допол­ни­тель­но про­ве­рить, не теря­ет­ся ли зна­че­ние this или $ при исполь­зо­ва­нии внут­ри функ­ции;
  • есть ли внут­ри вашей пере­мен­ной или объ­ек­та вооб­ще что-нибудь, с чем мож­но рабо­тать.

Попробуйте сами

У вас есть стра­ни­ца с эле­мен­том <h1 id="text-test"></h1> и JavaScript-кодом. При повтор­ном запус­ке ани­ма­ции он пада­ет с нашей ошиб­кой. Попро­буй­те выяс­нить, поче­му так про­ис­хо­дит.

document.addEventListener('DOMContentLoaded', function (event) {
  var dataText = ["Test", "Hello", "Salut", "Bonjour"];
  function typeWriter(text, i, fnCallback) {
    if (i < (text.length)) {
      document.getElementById("text-test").innerHTML = text.substring(0, i + 1) + '<span aria-hidden="true"></span>';
      setTimeout(function () {
        typeWriter(text, i + 1, fnCallback)
      }, 100);
    }
    else if (typeof fnCallback == 'function') {
      setTimeout(fnCallback, 700);
    }
  }
  function StartTextAnimation(i) {
    if (typeof dataText[i] == 'undefined') {
      setTimeout(function () {
        StartTextAnimation(0);
      }, 10000);
    }
    // ВОТ ТУТ ОШИБКА ↓
    if (i < dataText[i].length) {
      typeWriter(dataText[i], 0, function () {
        StartTextAnimation(i + 1);
      });
    }
  }
  StartTextAnimation(0);
});