首页 > 解决方案 > 在 module.exports 之后尝试访问定义的函数时会引发 TypeError

问题描述

所以我参加了关于 JS 的 udemy 课程,在制作应用程序期间,他编写了如下代码。当我开始运行代码时,会出现一个错误,提示“TypeError:this.validate 不是函数”。我尝试了不同的导出 User 的方法,有时它告诉我它无法将 User 读取为我想要的构造函数。在过去的 4 个小时里,我一直在做这个,但我仍然无法弄清楚它是如何工作的。其他文件需要整个文件。当在这些其他文件上时,我创建了一个对象的实例,如下所示。尽管当我调用 pushError 函数时无法访问数组的 .push 方法(弹出错误消息),但它仍然有效

const User = require('../models/User.js')

let user = new User(req.body);
//I can then run the .validate function
user.validate();
//But in that function another error raises that says that the 
//"push cannot be accessed in undefined" 
//And it leads me to think that during the construction the 
//empty list becomes undefined????

let User = function(data) {{
    this.username = data.username;
    this.mail = data.email;
    this.password = data.password;
    this.errors = [];
}
}

User.prototype.validate = function(){
    if(this.username.replace(" ","") == ""){pushError("Username")}
    if(this.password == ""){pushError("Password")}
    if(this.mail.replace(" ","") == ""){pushError("Email")}
}

User.prototype.register = ()=>{
    //Step #1: Validate user Data
    this.validate();
    //Step #2:If validated store data to DB
}

function pushError(str){
    
    this.errors.push(`You must provide a valid ${str}.`);
};

module.exports = User;

如果您通读所有这些,谢谢!

标签: javascriptnode.jsconstructortypeerrormodule.exports

解决方案


问题是您的pushError函数与User您正在创建的实例没有任何关系。

内部pushError,this不是User您尝试创建的新对象,因此this.errors是,undefined并且您不能调用push.undefined

此外,写成register箭头函数而不是常规函数会使其失去this(this成为封闭上下文的值,window在浏览器或globalNode.js 中)。

解决这个问题涉及三个步骤。

首先,您应该重写pushErrorUser的原型链的一部分,如下所示:

User.prototype.pushError = function(str) {
    this.errors.push(`You must provide a valid ${str}.`);
};

其次,您应该使用this.pushError而不是pushErrorin validate

User.prototype.validate = function() {
    if (this.username.replace(" ", "") == "") {
        this.pushError("Username");
    }
    if (this.password == "") {
        this.pushError("Password");
    }
    if (this.mail.replace(" ","") == "") {
        this.pushError("Email");
    }
}

第三,写成register常规函数:

User.prototype.register = function() {
    //Step #1: Validate user Data
    this.validate();
    //Step #2:If validated store data to DB
}

那应该这样做。现在,一些额外的评论和资源。它可能会帮助您:

  • 深入了解 MDN 上的JavaScript 对象,尤其是对象原型部分。
  • 将您的代码编写为 ES6 类,这是一种更“现代”的方式来做同样的事情:本文给出了如何以“原型方式”或使用类来编写事物的示例。
  • 在本文中详细了解常规函数和“胖箭头”函数之间的区别。

推荐阅读