根据问题的标题,这个问题可能有几个重复,但我有一个非常具体的情况。
我正在构建一个节点模块示例代码
var myModule = function() {
// do something init
};
myModule.prototype.a = 10;
myModule.prototype.b = 20;
myModule.prototype.method1 = function() {
// in this method I can access a and b using this
this.a
this.b
};
myModule.prototype.method2 = function() {
// I can call method1 here
this.method1();
};
这适用于下面提到的案例
var myModule = require('myModule');
var instance = new myModule();
在实例上调用method2可以正常工作
instance.method2 // this should work fine
现在假设我将method2作为回调函数传递给表达式或任何其他函数,如下面的
someobject.performsomeasync(instance.method2); // this will fail
据我所知,JavaScript原型会失败,因为在这种情况下this
将引用不是instance
的调用者对象
如何让它发挥作用? 我正在做的是一个很好的编码实践?
答案 0 :(得分:1)
您可以通过bind方法提供this
:
someobject.performsomeasync(instance.method2.bind(instance));
另一种解决方案:
someobject.performsomeasync(function() {
instance.method2();
});
UPD1
在我们的讨论之后,您总是希望对象的方法 将在对象实例的上下文中执行。然后你可以这样做:
var myModule = function() {
this.method1 = method1.bind(this);
this.method2 = method2.bind(this);
};
myModule.prototype.a = 10;
myModule.prototype.b = 20;
function method1() {
// in this method I can access a and b using this
this.a
this.b
};
function method2() {
// I can call method1 here
this.method1();
};
但这是非常糟糕的风格。您图书馆的用户是javascript开发人员。因此,他们必须知道您是否通过了回调,例如someobject.performsomeasync(instance.method2)
,您只需传递对象的方法,而不是上下文。因此,他们必须使用bind
来提供背景信息。
PS 顺便提一下,我建议您不要在原型中定义对象的属性。定义方法(也许是常量)。它非常容易出错。例如,如果您的属性是对象,那么有人可以编写下一个代码:
instance.someobject.a = 10;
他将为a
属性更改所有实例的someobject
。