这个范围随着继承而丢失

时间:2013-09-24 19:11:51

标签: javascript node.js oop

以下是示例代码,两个文件和“类”。

使用已定义方法的CRUD类,this.modelName会出现问题,因为我使用此代码设置此上下文更改的路由:

问题是如何在CRUD中获得定义modelName的相同范围?

server.get('/users/:id', UserRoutes.find);

代码:

var db = require('../models');

function CRUD(modelName) {
    this.modelName = modelName;
    this.db = db;
}

CRUD.prototype = {

    ping: function (req, res, next) {
        res.json(200, { works: 1 });
    },

    list: function (req, res, next) {

        // FAILS BECAUSE the modelName is undefined
        console.log(this);

        db[this.modelName].findAll()
            .success(function (object) {
                res.json(200, object);
            })
            .fail(function (error) {
                res.json(500, { msg: error });
            });
    }
};

module.exports = CRUD;

UserRoutes类:

var CRUD = require('../utils/CRUD'),
util = require('util');

var UserModel = function() {
    UserModel.super_.apply(this, arguments);
};

util.inherits(UserModel, CRUD);

var userRoutes = new UserModel('User');

module.exports = userRoutes;

2 个答案:

答案 0 :(得分:2)

我假设你在其他地方使用userRoutes.list作为处理程序,即上下文发生了变化。在这种情况下,这应该是一个简单的解决方案:

function CRUD(modelName) {
    this.modelName = modelName;
    this.db = db;
    this.list = CRUD.prototype.list.bind(this);
}

请注意,您将无法使用该解决方案访问“其他this”(this将永久绑定到CRUD个实例,无论.list如何被称为。)

另一个选项是将list转换为函数生成器(与.bind完全相同,除了您仍然可以使用其他上下文中的this:< / p>

CRUD.prototype = {
    // some code

    list: function() {
        var that = this;
        return function (req, res, next) {
            console.log(that);

            db[that.modelName].findAll()
                .success(function (object) {
                    res.json(200, object);
                })
                .fail(function (error) {
                    res.json(500, { msg: error });
                });
        }
    }
};

然后使用userRoutes.list()作为处理程序。

答案 1 :(得分:0)

通常通过将this存入_this来修复此类事情。在列表中,函数this是函数对象,它没有modelName对象。

var _this; 

function CRUD(modelName) {
    this.modelName = modelName;
    this.db = db;
    _this = this // <---------------
}

.... 
// call the _this in the outer scope 
db[_this.modelName]