2017-02-10 5 views
0

поэтому здесь ситуация есть. У меня есть функция-конструктор со многими свойствами и методами. вот свойство:JavaScript - var self = this; self не определено

var Brain = function(){ 
    this.util = require('util'); 
    this.fs = require('fs'); 
    this.assert = require('assert'); 
    this.Sequelize = require('sequelize'); 
    this.JsonField = require('sequelize-json'); 
    this.bcrypt = require('bcrypt-nodejs'); 
    this.bodyParser = require('body-parser'); 
    this.fileUpload = require('express-fileupload'); 

    // Custom Modules 
    this.ModelsModule = require('./models'); 
    this.TombModule = require('./tomb'); 

} 

несколько методов определяются для вызова данного обратного вызова и передавать данные на него, например:

Brain.prototype.db_read = function(request, response, data, callback) { 
    var self = this; 

    self.ModelsModule[data.Model].findOne(data.where) 
    .then(function(obj) { 
    // console.log(obj); 
    callback(request, response, obj); 
    }) 
    .catch(function(error){ 
    console.log(error); 

    }); 

} 

Вот вещь - функция обратного вызова всегда будет другим методом одной и той же функции-конструктора. вот еще один метод, который был бы обратный вызов:

Brain.prototype.login = function(request, response, user) { 
    var self = this; 

    // console.log('form-data --- ', request.body); 

    if(user == null || user == undefined) { 
    console.log('Account Load: Failed'); 
    return response.render(self.TombModule.pages['login'], {error: 'Invalid Credentials'}); 
    } 
    else { 
    // console.log(user.dataValues); 
    if(self.bcrypt.compareSync(request.body.pswrd, user.dataValues.pswrd) == false) { 
     console.log('Account Load: Failed'); 
     return response.render(self.TombModule.pages['login'], {error: 'Invalid Credentials'}); 
    } 
    console.log('Account Load: Successful'); 
    request.session.you = { 
     id: user.dataValues.id, 
     f_name: user.dataValues.f_name, 
     m_initial: user.dataValues.m_initial, 
     l_name: user.dataValues.l_name, 
     icon: user.dataValues.icon, 
     background: user.dataValues.background, 
     email: user.dataValues.email, 
     phone: user.dataValues.phone, 
     fax: user.dataValues.fax, 
     uv: user.dataValues.uniqueValue 
    }; 
    return response.redirect('/home'); 
    } 

} 

В моем app.js новый экземпляр мозга создаются.

const RoutinesModule = require('./routines'); 
const brain = new RoutinesModule.Brain(); 

Вся цепочка событий начинается с экспресс-маршрут POST:

app.post('/login', function(request, response){ 

    var data = { 
    Model: 'Users', 
    where: {where: {email: request.body.email}} 
    } 

    brain.db_read(request, response, data, brain.login); 

}); 

Обратите внимание, что обратный вызов, последний параметр, для Brain.db_read является Brain.login, что является еще одним способом из тот же конструктор. здесь возникает проблема.

Когда запросы POST к /login попадает в app.js, это будет запрашивать базу данных и дать результаты в той или иной функции, чтобы справиться с этим, в этом случае Brain.login

внутри Brain.db_read() , var self = this; работает. он указывает на себя, экземпляр Мозга. однако, когда он вызывает обратный вызов, который является Brain.login, утверждение внутри Brain.login, var self = this; не работает. это приводит к неопределенному, вызывая ошибку.

Почему это происходит? почему var self = this; внутри Brain.login приводит к неопределенности?

В конечном итоге то, что я пытаюсь сделать, это создать набор основных функций для обработки операций с базой данных (CRUD) вместо выполнения операций с базой данных внутри каждой отдельной функции, которая/может быть неопределенной суммой.

Я мог бы просто потребовать, чтобы модуль в определении этой функции, но я бы очень хотел получить доступ к его свойству для динамических, масштабируемых и эффективных средств.

Спасибо!

+0

Созданная вами переменная 'self' будет находиться в области видимости в этой функции обратного вызова, где вы вызываете' console.log (obj) 'и' callback (request, response, obj) '. Вы могли бы, например, использовать 'callback.call (self, request, response, obj)'. Но «я» из этой области не становится магически доступным в рамках этого метода «login». – Bergi

ответ

3

Вы передаете метод brain.login как функцию, у которой нет владельца. Вы просто передаете ссылку на функцию. Вам нужно сделать brain.login.bind(brain).

+0

Ничего себе, узнайте что-то новое каждый день. Благодаря! это все решило! так и общий подход к определению владельца функции при работе с параметрами обратного вызова? просто добавить объект .bind() с объектом, которым мы хотим быть владельцем обратного вызова? – ryanwaite28

+0

Супер быстрый ответ тоже! A + – ryanwaite28

+0

'bind' хорошо работает в этих сценариях. Не использовать 'this' или' new' работает еще лучше. –

Смежные вопросы