Ошибка JavaScript: "не является функцией"
Похоже, что "$ 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();
Затем в другом script я пытаюсь использовать этот 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));
, он даст мне пустое предупреждение.
Что мне не хватает?
Ответы
Ответ 1
Функция 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();
Ответ 2
Для более общих советов по устранению проблем такого рода в MDN есть хорошая статья TypeError: "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();
Ответ 3
Я получил эту ошибку, потому что у меня была круговая зависимость. Может быть, это поможет кому-то еще.
Ответ 4
Я также ударил эту ошибку. В моем случае основная причина была связана с асинхронностью (во время рефакторинга кодовой базы): асинхронная функция, которая создает объект, которому принадлежит функция "не функция", не ожидалась, и последующая попытка вызвать функцию выдает ошибку, например ниже:
const car = carFactory.getCar();
car.drive() //throws TypeError: drive is not a function
Исправление было:
const car = await carFactory.getCar();
car.drive()
Публикация этого случая поможет любому, кто столкнется с этой ошибкой.