【问题标题】:"Uncaught TypeError: undefined is not a function" Error message in Javascript when calling a method in an object“未捕获的类型错误:未定义不是函数”调用对象中的方法时 Javascript 中的错误消息
【发布时间】:2014-06-25 15:37:34
【问题描述】:

我从 HTML 中的按钮调用函数时遇到问题,它给了我:“未捕获的类型错误:未定义不是函数”错误。我不认为这里有什么问题。或者有一些我没有考虑到的东西。提前感谢您的回答!

我有很多 JS 文件,这是因为这是一个学校作业,我们现在正在学习模型、视图、控制器 (MVC) 方法。

我有这个按钮:

<button onClick="ControllerBKE.reageerOpKlik()">Ok!</button>

然后我有这个 Javascript 代码创建一个对象 ^“ControllerBKE”:

"use strict"
window.onload = reageerOpStart();

function reageerOpStart()
{
    var controllerBKE = new ControllerBKE();
}

这是“ControllerBKE”中应该但没有对按钮做出反应的代码行:

function ControllerBKE(){
    this.reageerOpKlik = reageerOpKlik;

    function reageerOpKlik(){
        alert('hoi');
    }
}

这只是大代码的一小部分。但是当我点击按钮而不是收到带有“hoi”的警报时,我收到了错误消息。

【问题讨论】:

  • 作为一个旁注,只是为了良好的实践,尽量避免像OnClick=""属性那样的内联javascript,而是使用element.addEventListener("click", function(){})
  • @Lior 这听起来像是一个更简单的解决方案,如果我有多个按钮,我如何将该行指定给一个按钮?
  • @user3775849 如果您有多个按钮,请在容器(如文档)上设置 onclick,然后使用 event.target 找出被点击的内容并采取相应措施:document.onclick=funciton(e){ControllerBKE.reageerOpKlik(e);} 并在 reageerOpKlik 中使用 e.target因为除非您使用 IE,否则这是被点击的东西,因为他们使用 window.event 而不是将事件作为参数传递。有关构造函数、原型和this 的值的更多信息可以在这里找到:stackoverflow.com/a/16063711/1641941
  • @user3775849 你可以像 HMR 写的那样监听容器上的事件,这在内存方面更好,或者如果你正在动态添加元素。如果这些不是问题(因为这是一项学校作业),您可以采取更简单的方法,并为带有 ID 或类的按钮使用独特的选择器。假设您向该按钮添加了一个 ID id="okBtn" 然后您可以查询该元素 var okBtn = document.querySelector("#okBtn"); 然后在事件侦听器中使用它:okBtn.addEventListener("click", YOUR_CALLBACK_FUNCTION) 其中 YOUR_CALLBACK_FUNCTION 是您的回调函数:)
  • 感谢您的帮助,但现在我得到“未捕获的类型错误:无法读取 null 的属性 'addEventListener'”我已经完全按照您所说的做了。我已将所有代码发布到 pastebin:HTMLCSSJS。一次粘贴一次,所有 javascripts 都会受到影响。我真的希望我犯了一个愚蠢的错误,而且很容易修复.. ;)

标签: javascript html function button


【解决方案1】:

reageerOpKlik 是一个实例方法。您必须从实例中使用它。最简单的解决方案(不是最好的)是创建一个全局控制器实例。有很多方法可以摆脱该全局变量,但这超出了问题的范围。

function reageerOpStart()
{
    window.controllerBKE = new ControllerBKE();
}


<button onClick="window.controllerBKE.reageerOpKlik()">Ok!</button>

【讨论】:

  • 感谢您的回复! :D 但这对我不起作用.. :( 现在我得到:“Uncaught TypeError: Cannot read property 'reageerOpKlik' of undefined”
  • 这一定意味着你的代码没有调用reageerOpstart。你调试了吗?您是否检查了它是否被调用并正在设置全局?
【解决方案2】:

问题是你的代码

<button onClick="ControllerBKE.reageerOpKlik()">Ok!</button>

正在尝试在您的原型对象 ControllerBKE 上调用 reageerOpKlik

你的意思可能是

<button onClick="controllerBKE.reageerOpKlik()">Ok!</button>

其中controllerBKE 是原型的一个实例。

但是,您还有另一个问题。功能:

function reageerOpStart()
{
    var controllerBKE = new ControllerBKE();
}

reageerOpStart 函数的范围内创建controllerBKE,这意味着它在全局范围内不可用,这是您的按钮单击处理程序所期望的。

您可能需要考虑:

 <button onClick="APP.controllerBKE.reageerOpKlik()">Ok!</button>

 APP = {}
 function reageerOpStart()
 {
     APP.controllerBKE = new ControllerBKE();
 }

或者,更好的是:

 <button id="myButton">Ok!</button>

 function reageerOpStart()
 {
     var controllerBKE = new ControllerBKE();
     document.getElementById("myButton").addEventListener("click", function() {
            controllerBKE.reageerOpKlik();
     });
 }

【讨论】:

    【解决方案3】:

    您所拥有的称为closure。您的功能范围有限。也就是说,它只能在定义它的ControllerBKE()内部调用,不能从函数外部调用。

    您实际上所做的是通过ControllerBKE 实例上的属性公开该闭包。虽然这可行,但它更适合 JavaScript 的原型结构,以将其添加到 ControllerBKE.prototype

    重要的是要记住 JavaScript 原型而不是面向对象。虽然这可能类似于面向对象的封装,但两者有不同的概念和用途。

    看下面的例子:

    HTML:

    <button onclick="controllerBKE.reageerOpKlik()">Ok!</button>
    

    JavaScript:

    "use strict";
    window.controllerBKE = new ControllerBKE();
    
    function ControllerBKE () { }
    
    ControllerBKE.prototype.reageerOpKlik = function () {
        alert('hoi');
    }
    

    我已经简化了您的一些代码并对其进行了重构,以支持 JavaScript 为我们提供的 prototype 对象。

    第一行是将controllerBKE 变量添加到窗口对象。这为它提供了整个页面的全局范围,允许您的 onclick 函数访问它。

    下一行是一个简单的函数包装器。这将创建一个ControllerBKE 类型为object 的实例。

    您尝试调用的函数现在附加到ControllerBKE 的原型。这意味着使用new 关键字创建的ControllerBKE 的任何实例都可以访问此函数。

    在下面的小提琴中查看完整的功能:

    FIDDLE

    参考资料:

    Object.prototype

    Object Oriented JavaScript

    【讨论】:

    • @user3775849 没问题。祝你好运,编码愉快! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 2015-03-14
    • 2014-12-13
    相关资源
    最近更新 更多