Javascript:创建持久绑定函数

Javascript:创建持久绑定函数,javascript,binding,prototype,this,Javascript,Binding,Prototype,This,我意识到这样的问题经常被问到(在过去的几天里,我可能已经阅读了其中的每一个问题,试图了解如何解决这个问题)——但在这种情况下,虽然我很有信心我知道为什么会发生这种情况,但我正在努力实施一个实际的解决方案 我正在使用Node.js构建一个小应用程序,但在创建一个带有原型函数的对象时遇到了麻烦,因为原型函数在传递时不会丢失绑定 以下是我目前掌握的情况: foo.js var Foo = module.exports = function(server) { this.server = ser

我意识到这样的问题经常被问到(在过去的几天里,我可能已经阅读了其中的每一个问题,试图了解如何解决这个问题)——但在这种情况下,虽然我很有信心我知道为什么会发生这种情况,但我正在努力实施一个实际的解决方案

我正在使用Node.js构建一个小应用程序,但在创建一个带有原型函数的对象时遇到了麻烦,因为原型函数在传递时不会丢失绑定

以下是我目前掌握的情况:

foo.js

var Foo = module.exports = function(server) {
    this.server = server;
    // some other stuff
};

Foo.prototype.send = function(data) {
    server.doStuff(data);
};

Foo.prototype.sendData = function(data) {
    // do stuff with data;
    this.send(data);
};
var Bar = module.exports = function() {
    this.dataStore = // data store connection;
};

Bar.prototype.getSomething(data, callback) {
    this.dataStore.get(data, function(err, response) {
        callback(response);
    });
};
var Foo = require('./foo');
var Bar = require('./bar');
var aFoo = new Foo(server);
var aBar = new Bar();

// at some point do:
aBar.getSomething(data, aFoo.sendData);
bar.js

var Foo = module.exports = function(server) {
    this.server = server;
    // some other stuff
};

Foo.prototype.send = function(data) {
    server.doStuff(data);
};

Foo.prototype.sendData = function(data) {
    // do stuff with data;
    this.send(data);
};
var Bar = module.exports = function() {
    this.dataStore = // data store connection;
};

Bar.prototype.getSomething(data, callback) {
    this.dataStore.get(data, function(err, response) {
        callback(response);
    });
};
var Foo = require('./foo');
var Bar = require('./bar');
var aFoo = new Foo(server);
var aBar = new Bar();

// at some point do:
aBar.getSomething(data, aFoo.sendData);
main.js

var Foo = module.exports = function(server) {
    this.server = server;
    // some other stuff
};

Foo.prototype.send = function(data) {
    server.doStuff(data);
};

Foo.prototype.sendData = function(data) {
    // do stuff with data;
    this.send(data);
};
var Bar = module.exports = function() {
    this.dataStore = // data store connection;
};

Bar.prototype.getSomething(data, callback) {
    this.dataStore.get(data, function(err, response) {
        callback(response);
    });
};
var Foo = require('./foo');
var Bar = require('./bar');
var aFoo = new Foo(server);
var aBar = new Bar();

// at some point do:
aBar.getSomething(data, aFoo.sendData);
正如您可能想象的那样,将aFoo.sendData函数作为回调传递会导致它丢失与aFoo的绑定,因此它无法在Foo上找到“send”函数


如何修改Foo,使sendData保持其与Foo的绑定?是否有更好的方法来构造此代码,使其不必这样做?

您只需将对aFoo.sendData的调用包装在一个匿名函数中:

aBar.getSomething(data, function () {
    aFoo.sendData();
});

由于您引用了
aFoo.sendData
,因此
sendData
中对
this
的引用不再是
aFoo
。使用匿名函数时,您没有引用该函数;您只需在
aFoo
实例上将其作为方法调用,因此
仍然是
aFoo

您只需将对aFoo.sendData的调用包装在一个匿名函数中:

aBar.getSomething(data, function () {
    aFoo.sendData();
});

由于您引用了
aFoo.sendData
,因此
sendData
中对
this
的引用不再是
aFoo
。使用匿名函数时,您没有引用该函数;您只是将其作为
aFoo
实例上的一个方法调用,因此
这个
仍然是
aFoo

很棒!这似乎部分起作用;但我需要将“data”传递给sendData,这意味着我必须实际使用:aBar.getSomething(data,function(data){aFoo.sendData(data);}(据我所知)-当我已经将数据作为参数传递时,这似乎有点不必要。有什么想法吗?@Tom:这有点痛苦,但在JavaScript中非常常见。如果你有很多参数,并且你不想全部重新键入,你可以做
function(){sendData.apply(aFoo,arguments);}
,它将使用提供给匿名函数的任何参数自动填充
sendData
的参数(不过,从技术上讲,如果参数变得那么长,则应将其作为单个对象传递,而不是单独传递…).为非常有用的响应干杯,现在开始变得更有意义了!太好了!这似乎部分有效;但我需要将“数据”传递给sendData,这意味着我必须实际使用:aBar.getSomething(数据,函数(数据){aFoo.sendData(数据);}(据我所知)-当我已经将数据作为参数传递时,这似乎有点不必要。有什么想法吗?@Tom:这有点痛苦,但在JavaScript中非常常见。如果你有很多参数,并且你不想全部重新键入,你可以做
function(){sendData.apply(aFoo,arguments);}
,它将使用提供给匿名函数的任何参数自动填充
sendData
的参数(不过,从技术上讲,如果参数变得那么长,则应将其作为单个对象传递,而不是单独传递…).为非常有用的回答干杯,现在开始变得更有意义了!