使用nodejs封装继承对象的属性

时间:2014-03-20 03:58:05

标签: javascript node.js inheritance scope

我在node.js中编写了一个API(而且我用js编写了一个n00b)。我有一个父资源方法,我希望为每个特定资源扩展以干掉我的代码。这就是我所拥有的

resource.js:

function Resource(model) {
   this.Model = model;
};


Resource.prototype.getAll = function(req, res) {
   this.Model.find(req.query).exec(function(err, all) {
      ...
   };
};

module.exports = Resource;

user.js的:

var mongoose = require("mongoose"),
   inherits = require('util').inherits,
   Model = require('./resource.js'),
   UserModel = mongoose.model('User');;

function User() {
   Model.call(this, UserModel);
};

inherits(User, Model);

module.exports = new User();

artist.js

var mongoose = require("mongoose"),
   inherits = require('util').inherits,
   Model = require('./resource.js'),
   ArtistModel = mongoose.model('Artist');

function Artist() {
   Model.call(this, ArtistModel);
};

inherits(Artist, Model);

module.exports = new Artist();

然后在我的路线中,我做了:

var UserResource = require('./user2.js'),
   ArtistResource = require('./artist2.js');

app.get('/api/user', UserResource.getAll);

当我尝试点击/ api / user时,我在尝试调用this.Model.find()时收到未定义的错误。

我也尝试在resource.js中设置一个全局Model var,但是当它调用require('./artist2.js')时会被覆盖

如何获得类似于更多OO语言的封装...甚至更好,在JavaScript中这样做的推荐方法是什么?我希望能够通过执行一些预处理然后调用父函数来扩展子代中的函数。

1 个答案:

答案 0 :(得分:1)

我认为问题可能在于您将此类方法作为回调传递:

app.get('/api/user', UserResource.getAll);

这最终传递了对该方法的引用,但随后调用该方法时没有对象引用,因此未正确设置this指针。

有点像这样:

var f = UserResource.getAll;
f();

这最终调用getAll()而没有任何对象引用,因此this指针未设置为该对象。

有很多方法可以解决这个问题,但最简单的方法可能是使用.bind()这样:

app.get('/api/user', UserResource.getAll.bind(UserResource));

这将创建一个小函数存根,然后实际调用UserResource.getAll()而不是仅调用getAll(),并通过回调将方法绑定到适当的对象,从而设置{{1}适当的指针。

这必须在您将方法作为回调传递时进行,并且需要在相应对象的上下文中调用它(方法几乎总是如此)。