Ошибка JavaScript: «это не функция» - PullRequest
16 голосов
/ 22 марта 2012

Похоже, что "$ smth - это не функция" - очень распространенная проблема с JavaScript, но после просмотра нескольких потоков я все еще не могу понять, что вызывает его в моем случае.

У меня есть пользовательский объект, определенный как:

function Scorm_API_12() {
var Initialized = false;

function LMSInitialize(param) {
    errorCode = "0";
    if (param == "") {
        if (!Initialized) {
            Initialized = true;
            errorCode = "0";
            return "true";
        } else {
            errorCode = "101";
        }
    } else {
        errorCode = "201";
    }
    return "false";
}

// some more functions, omitted.
}

var API = new Scorm_API_12();

Затем в другом скрипте я пытаюсь использовать этот API следующим образом:

var API = null;

function ScormProcessInitialize(){
    var result;

    API = getAPI();

    if (API == null){
        alert("ERROR - Could not establish a connection with the API.");
        return;
    }

    // and here the dreaded error pops up
    result = API.LMSInitialize("");

    // more code, omitted
    initialized = true;
}

Материал getAPI () выглядит следующим образом:

var findAPITries = 0;

function findAPI(win)
{
   // Check to see if the window (win) contains the API
   // if the window (win) does not contain the API and
   // the window (win) has a parent window and the parent window
   // is not the same as the window (win)
   while ( (win.API == null) &&
           (win.parent != null) &&
           (win.parent != win) )
   {
      // increment the number of findAPITries
      findAPITries++;

      // Note: 7 is an arbitrary number, but should be more than sufficient
      if (findAPITries > 7)
      {
         alert("Error finding API -- too deeply nested.");
         return null;
      }

      // set the variable that represents the window being
      // being searched to be the parent of the current window
      // then search for the API again
      win = win.parent;
   }
   return win.API;
}

function getAPI()
{
   // start by looking for the API in the current window
   var theAPI = findAPI(window);

   // if the API is null (could not be found in the current window)
   // and the current window has an opener window
   if ( (theAPI == null) &&
        (window.opener != null) &&
        (typeof(window.opener) != "undefined") )
   {
      // try to find the API in the current window�s opener
      theAPI = findAPI(window.opener);
   }
   // if the API has not been found
   if (theAPI == null)
   {
      // Alert the user that the API Adapter could not be found
      alert("Unable to find an API adapter");
   }
   return theAPI;
}

Теперь API , вероятно, найден, поскольку я не получаю сообщение "Невозможно найти ...", код продолжает пытаться его инициализировать. Но firebug говорит мне API.LMSInitialize is not a function, и если я пытаюсь отладить его с помощью alert(Object.getOwnPropertyNames(API));, он выдает мне пустое предупреждение.

Чего мне не хватает?

Ответы [ 3 ]

19 голосов
/ 13 октября 2016

Для получения более общего совета по устранению неполадок такого рода у MDN есть хорошая статья Ошибка типа: "x" не является функцией :

Этобыла предпринята попытка вызвать значение как функцию, но на самом деле значение не является функцией.Какой-то код ожидает, что вы предоставите функцию, но этого не произошло.

Может быть, в названии функции есть опечатка?Может быть, объект, для которого вы вызываете метод, не имеет этой функции?Например, у объектов JavaScript нет функции отображения, но у объекта JavaScript Array.

По сути, объект (все функции в js также являются объектами) не существует там, где вы думаете, что он существует.Это может быть по многочисленным причинам , включая (не расширенный список):

  • отсутствует библиотека скриптов
  • опечатка
  • Функция находится в области, к которой у вас в данный момент нет доступа, например:

var x = function(){
   var y = function() {
      alert('fired y');
   }
};
    
//the global scope can't access y because it is closed over in x and not exposed
//y is not a function err triggered
x.y();
  • Ваш объект / функция не имеет функции, которую вы вызываете:

var x = function(){
   var y = function() {
      alert('fired y');
   }
};
    
//z is not a function error (as above) triggered
x.z();
14 голосов
/ 22 марта 2012

Ваша функция LMSInitialize объявлена ​​внутри функции Scorm_API_12.Так что это можно увидеть только в области действия Scorm_API_12.

Если вы хотите использовать эту функцию как API.LMSInitialize(""), объявите Scorm_API_12 функцию следующим образом:

function Scorm_API_12() {
var Initialized = false;

this.LMSInitialize = function(param) {
    errorCode = "0";
    if (param == "") {
        if (!Initialized) {
            Initialized = true;
            errorCode = "0";
            return "true";
        } else {
            errorCode = "101";
        }
    } else {
        errorCode = "201";
    }
    return "false";
}

// some more functions, omitted.
}

var API = new Scorm_API_12();
1 голос
/ 11 мая 2019

Я тоже попал в эту ошибку. В моем случае основная причина была связана с асинхронностью (во время рефакторинга кодовой базы): асинхронная функция, которая создает объект, которому принадлежит функция «не функция», не ожидалась, и последующая попытка вызвать функцию выдает ошибку, например ниже:

const car = carFactory.getCar();
car.drive() //throws TypeError: drive is not a function

Исправление было:

const car = await carFactory.getCar();
car.drive()

Публикация этого сообщения помогает любому, кто столкнулся с этой ошибкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...