【问题标题】:JavaScript error: "is not a function"JavaScript 错误:“不是函数”
【发布时间】:2012-04-07 04:17:50
【问题描述】:

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

我错过了什么?

【问题讨论】:

  • 在API = getAPI(); 之后执行console.log(API) 会得到什么?
  • 请你告诉我你想在初始化后做什么..
  • 我得到了那个错误,因为我有一个循环依赖。也许这会对其他人有所帮助。

标签: javascript javascript-objects


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    当我使用 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());
    

    【讨论】:

      【解决方案3】:

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

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

      解决方法是:

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

      发布此内容可以帮助其他面临此错误的人。

      【讨论】:

        【解决方案4】:

        有关调试此类问题的更多通用建议 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();

        【讨论】:

        • 我想补充一点:命名一个局部变量和一个函数是一样的,所以当你调用showOrderForm()时showOrderForm的类型是一个布尔值。
        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-06-27
          • 2011-06-20
          • 2020-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多