定义的函数在 module.exports 之后尝试访问时引发 TypeError

Defined function raises TypeError when tried to be accessed after module.exports

所以我参加了一个关于 JS 的 udemy 课程,在制作应用程序的过程中,他编写了下面编写的代码。当我来到 运行 代码时,会出现一个错误 "TypeError: this.validate is not a function"。我尝试了不同的导出 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;

如果您通读了所有内容,谢谢!

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

pushError 中,this 不是您要创建的新 User 对象,因此 this.errorsundefined,您不能在 undefined.

上致电 push

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

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

首先你应该重写 pushError 作为 User 原型链的一部分,像这样:

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

其次,你应该在validate中使用this.pushError而不是pushError

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
}

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

  • 深入 JavaScript Objects on MDN, especially the Object prototypes 部分。
  • 将您的代码编写为 ES6 class,这是一种更 "modern" 的方式来做同样的事情:this article 给出了如何编写 "prototype way" 或 classes.
  • this article.
  • 中详细了解常规函数和 "fat arrow" 函数之间的区别