web-dev-qa-db-fra.com

Erreur JavaScript: "n'est pas une fonction"

Il semble que "$ smth n'est pas une fonction" est un problème très courant avec JavaScript, mais après avoir parcouru pas mal de fils, je ne comprends toujours pas ce qui le provoque dans mon cas.

J'ai un objet personnalisé, défini comme:

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();

Ensuite, dans un script différent, j'essaie d'utiliser cette API de la manière suivante:

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;
}

Le truc getAPI (), ressemble à ceci:

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;
}

Maintenant, l'API est probablement trouvée, car je n'obtiens pas le message "Impossible de trouver ...", le code continue d'essayer de l'initialiser. Mais Firebug me dit API.LMSInitialize is not a function, Et si j'essaye de le déboguer avec alert(Object.getOwnPropertyNames(API));, il me donne une alerte vide.

Qu'est-ce que je rate?

19
SaltyNuts

Votre fonction LMSInitialize est déclarée dans la fonction Scorm_API_12. Il n'est donc visible que dans la portée de la fonction Scorm_API_12.

Si vous souhaitez utiliser cette fonction comme API.LMSInitialize(""), déclarez la fonction Scorm_API_12 Comme ceci:

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();
15
Just_Mad

Pour plus de conseils génériques sur le débogage de ce type de problème, MDN a un bon article TypeError: "x" n'est pas une fonction :

Il a été tenté d'appeler une valeur comme une fonction, mais la valeur n'est pas réellement une fonction. Certains codes s'attendent à ce que vous fournissiez une fonction, mais cela ne s'est pas produit.

Peut-être qu'il y a une faute de frappe dans le nom de la fonction? Peut-être que l'objet sur lequel vous appelez la méthode n'a pas cette fonction? Par exemple, les objets JavaScript n'ont pas de fonction de carte, contrairement aux objets de tableau JavaScript.

Fondamentalement, l'objet (toutes les fonctions de js sont également des objets) n'existe pas là où vous pensez qu'il existe. Cela peut être pour de nombreuses raisons , y compris (pas une liste exhaustive):

  • Bibliothèque de scripts manquante
  • Faute de frappe
  • La fonction est dans un périmètre auquel vous n'avez actuellement pas accès, par exemple:
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();
  • Votre objet/fonction n'a pas la fonction que vous appelez:
var x = function(){
   var y = function() {
      alert('fired y');
   }
};
    
//z is not a function error (as above) triggered
x.z();
19
Liam

J'ai également rencontré cette erreur. Dans mon cas, la cause principale était liée à l'async (lors d'un refactor de base de code): une fonction asynchrone qui construit l'objet auquel appartient la fonction "not a function" n'était pas attendue, et la tentative ultérieure d'invoquer la fonction lève l'erreur, exemple au dessous de:

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

Le correctif était:

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

La publication de cette incase aide toute autre personne confrontée à cette erreur.

2
0xadecimal