JavaScript错误:“不是函数”

时间:2012-03-22 15:10:40

标签: javascript javascript-objects

看起来“$ 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));调试它,它会给我一个空白警报。

我错过了什么?

6 个答案:

答案 0 :(得分:18)

有关调试此类问题的更多通用建议,MDN有一篇好文章TypeError: "x" is not a function

  

尝试调用类似函数的值,但值不是   实际上是一个功能有些代码希望您提供一个函数,但是   那并没有发生。

     

也许函数名中有拼写错误?也许你是对象   调用方法on没有这个功能?例如,   JavaScript对象没有map函数,但是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();




答案 1 :(得分:14)

您的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 :(得分:2)

我遇到了这个错误,因为我有一个循环依赖。也许这会帮助别人。

答案 3 :(得分:0)

我也遇到了这个错误。在我的案例中,根本原因是与异步相关的(在代码库重构期间):没有等待构建“非函数”函数所属对象的异步函数,并且随后尝试调用该函数会引发错误,例如下方:

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

解决方法是:

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

发布此情况以帮助其他人遇到此错误。

答案 4 :(得分:0)

当我使用 JSON.parse 和 JSON.stringify() 复制类对象时收到此错误,该类对象删除了如下函数:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Method
  calcArea() {
    return this.height * this.width;
  }
}

const square = new Rectangle(10, 10);

console.log('area of square: ', square.calcArea());

const squareCopy = JSON.parse(JSON.stringify(square));

// Will throw an exception since calcArea() is no longer function 
console.log('area of square copy: ', squareCopy.calcArea());

答案 5 :(得分:0)

除了上述流行的答案之外,如果您正在使用服务或辅助函数文件并对稍后将在项目中 export 的函数执行 import

确保您正在导入的函数名称与从服务、帮助程序或 utils 文件中导出的函数的确切名称相匹配 - 并且该函数确实存在于正确的文件中!我被这个错误卡住了,调试了几个小时,直到我发现这个错误。