我正在使用node.js.我有这个handlers.js文件:
exports.Handlers = function(prefix) {
this.prefix = prefix;
this.db = new DBInstance();
};
exports.Handlers.prototype.getItemById = function(id) {
var item = this.db.getItemById(id, function(error, item) {
item.name = this.prefix + item.name;
...
...
});
};
我打电话的时候:
var h = new Handlers();
h.getItemById(5);
我收到错误,因为上下文不是处理程序而且this.prefix不存在。我可以用这个解决它:
exports.Handlers.prototype.getItemById = function(id) {
var scope = this;
var item = this.db.getItemById(id, function(error, item) {
item.name = scope.prefix + item.name;
...
...
});
};
有没有更好的方法将上下文传递给回调? nodejs将上下文传递给回调的常用方法是什么?
答案 0 :(得分:17)
Node实现了ECMAScript 5,其中包含Function.bind()
。
我认为这就是你要找的东西。
exports.Handlers.prototype.getItemById = function(id) {
var item = this.db.getItemById(id, (function(error, item) {
item.name = this.prefix + item.name;
...
...
}).bind(this)); //bind context to function
};
这是有效的,但是当你使用闭包作为回调时,最常见的方法是将上下文存储在可以在闭包中使用的变量中。
这种方法比较常见,因为很多次回调都很深,每次回调调用bind
都很重;而定义self
一次很容易:
SomeObject.prototype.method = function(id, cb) {
var self = this;
this.getSomething(id, function(something) {
//self is still in scope
self.getSomethingElse(something.id, function(selse) {
//self is still in scope and I didn't need to bind twice
self.gotThemAll(selse.id, cb);
});
});
};
答案 1 :(得分:1)
这个问题与Node.js无关,这是JavaScript中的一个普遍问题 - 你已经找到了JavaScript中的常用解决方案:将this
上下文绑定到另一个变量(你调用的那个变量scope
1}}),并在回调中使用它来访问外部上下文。
此变量的常用名称包括that
和self
。
可能是ECMAScript 6(代号“和谐”)中的一个解决方案,它与所谓的胖箭头操作符将一个函数绑定到一个外部上下文。如果你今天想玩它,你可能想看看TypeScript,这是一个由Microsoft制作的JavaScript预编译器,它专注于与ES6兼容的语法。然后你的回调变成了诸如
之类的东西foo(() => { console.log(this.bar); });
而不是:
var that = this;
foo(function () { console.log(that.bar); });
仅仅为了完整性:jQuery(和其他框架)bind
函数通常类似。有关示例,请参阅http://api.jquery.com/bind/。
HTH。
答案 2 :(得分:-1)
这是常见的方式。您会发现名为scope
或self
的{{1}} var。
稍后编辑:
如果你想在另一个上下文中调用一个函数,可以这样:
_self