Определенная функция вызывает TypeError при попытке доступа после module.exports - PullRequest
0 голосов
/ 05 апреля 2020

Итак, я прошел курс удэми на JS и во время создания приложения он пишет код, который написан ниже. Когда я запускаю код, возникает ошибка: «TypeError: this.validate не является функцией». Я пробовал разные способы экспорта User, и иногда мне говорили, что он не может читать User как конструктор, как я хочу. Я занимался этим последние 4 часа и до сих пор не могу понять, как это работает. Весь файл требуется для других файлов. Когда в этих других файлах я создаю экземпляр объекта, как показано ниже. Он работает, хотя метод массива .pu sh недоступен (появляется сообщение об ошибке), когда я вызываю функцию pushError

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;

Если вы прочитали все это, спасибо!

1 Ответ

0 голосов
/ 05 апреля 2020

Проблема в том, что ваша функция pushError никак не связана с создаваемым вами экземпляром User.

Внутри pushError, this не является новым объектом User, который вы вы пытаетесь создать, следовательно, this.errors равно undefined, и вы не можете вызвать push для undefined.

Кроме того, запись register в виде функции стрелки вместо обычной функции делает ее потерять значение this (this становится значением окружающего контекста, window в браузере или global в Node.js).

Для решения этой проблемы необходимо выполнить три шага.

Сначала вы должны переписать pushError как часть цепочки прототипов User, например:

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

Во-вторых, вы должны использовать this.pushError вместо pushError в 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
}

Это должно сделать это. Теперь несколько дополнительных комментариев и ресурсов. Это может помочь вам:

  • Копаться в JavaScript Объекты в MDN, особенно в разделе Прототипы объектов .
  • Напишите ваш код как класс ES6, который является более «современным» способом сделать то же самое: в этой статье приведены примеры того, как писать вещи «прототипным способом» или с помощью классов.
  • Узнайте больше о различиях между обычными и «толстыми стрелками» в этой статье .
...