执行OOJavaScript回调时的作用域
各位-我正在努力学习如何编写OO Javascript,我来自as3 OO背景。。。 我遇到的问题是将一个类的方法作为回调传递给另一个类 在下面的示例中,我创建了AppController类的一个实例,并在其中创建了ConnectionMonitor类的一个实例。我将AppController的一个方法传递给ConnectionMonitor调用。回调可以正常工作,但回调函数中的内容似乎会使其(AppController)中的类的作用域松动 有什么想法吗执行OOJavaScript回调时的作用域,javascript,jquery,oop,callback,Javascript,Jquery,Oop,Callback,各位-我正在努力学习如何编写OO Javascript,我来自as3 OO背景。。。 我遇到的问题是将一个类的方法作为回调传递给另一个类 在下面的示例中,我创建了AppController类的一个实例,并在其中创建了ConnectionMonitor类的一个实例。我将AppController的一个方法传递给ConnectionMonitor调用。回调可以正常工作,但回调函数中的内容似乎会使其(AppController)中的类的作用域松动 有什么想法吗 //in the HTML <sc
//in the HTML
<script>
$(document).ready( function(){
new AppContoller().init();
});
</script>
//in the js file
//AppController Class
var AppContoller = function(){
this.body = $("body");
this.init = function(){
this.connection = new ConnectionMonitor();
this.connection.detectInitialConnection( this.initialConnectionDetected );
}
//callback function I pass
this.initialConnectionDetected = function(bool){
if(bool){
trace("app connected? "+bool); // logs - "app connected? true"
this.showOnlineSwf(); //thows error - "Object [object DOMWindow] has no method 'showOnline' "
}
else{
}
}
this.showOnlineSwf = function(){
trace("i'm online");
}
}
//ConnectionMonitor Class
var ConnectionMonitor = function()
{
this.detectInitialConnection = function(callbackFunction){
setTimeout(callbackFunction, 1000, [true]);
}
}
function trace(arg){
console.log(arg.toString());
}
//在HTML中
$(文档).ready(函数(){
新的AppContoller().init();
});
//在js文件中
//AppController类
var AppContoller=函数(){
this.body=$(“body”);
this.init=函数(){
this.connection=新的ConnectionMonitor();
this.connection.detectinialconnection(this.initialConnectionDetected);
}
//我传递的回调函数
this.initialConnectionDetected=函数(bool){
如果(bool){
跟踪(“应用程序已连接?”+bool);//日志-“应用程序已连接?真”
this.showOnlineSwf();//thows错误-“对象[Object DOMWindow]没有方法“showOnline”
}
否则{
}
}
this.showOnlineSwf=函数(){
trace(“我在线”);
}
}
//连接监视器类
var ConnectionMonitor=函数()
{
this.detectInitialConnection=函数(callbackFunction){
setTimeout(callbackFunction,1000,[true]);
}
}
函数跟踪(arg){
log(arg.toString());
}
修改init
将回调绑定到原始上下文:
this.init = function() {
this.connection.detectInitialConnection(
this.initialConnectionDetected.bind(this));
}
不幸的是,您可以在闭包中捕获this
的当前值以实现类似效果:
this.init = function() {
var that = this;
this.connection.detectInitialConnection(function(detected) {
that.initialConnectionDetected(detected);
});
}
另一种方法是使detectInitialConnection
能够处理可选的上下文参数:
this.detectInitialConnection = function(callbackFunction, _this){
setTimeout(function() {
callbackFunction.apply(_this || this, arguments);
}, 1000, [true]);
}
然后你会这样称呼它:
this.init = function() {
this.connection.detectInitialConnection(
this.initialConnectionDetected, this);
}
这些示例中的每一点都是从调用
DetectinialConnection
的上下文中保留对this
值的引用。this.initialConnectionDetected
将传递函数,但不包含应在实例上执行的信息
调用this.foo()
将传递此信息,但仅在直接调用时传递,而不是在传递和稍后调用时传递(这就是您正在做的)
必须使用例如绑定此信息(即此
值,即实例)。绑定
:
this.connection.detectInitialConnection(this.initialConnectionDetected.bind(this));
请注意,
.bind
在较旧的浏览器中不可用,但有模拟其行为的垫片可用。setTimeout将运行绑定到窗口的传递函数。您可以使用ES5覆盖此选项:
这在较旧的浏览器中不起作用,但提供的MDN链接有一个解决方法。其他答案是正确的,但似乎没有人提到Function.prototype.bind
是正确的。要使其正常工作,您需要包括。这在javascript中很棘手,尤其是当它涉及到构造函数和传递函数时。如果您这样做,它将工作:
//AppController Class
var AppContoller = function(){
this.body = $("body");
var self = this;
this.init = function(){
this.connection = new ConnectionMonitor();
this.connection.detectInitialConnection( this.initialConnectionDetected );
}
//callback function I pass
this.initialConnectionDetected = function(bool){
if(bool){
trace("app connected? "+bool); // logs - "app connected? true"
self.showOnlineSwf();
}
else{
}
}
this.showOnlineSwf = function(){
trace("i'm online");
}
}
谢谢,这在chrome中有效,但在FF 3.6中无效??FF说“his.initialConnectionDetected.bind不是函数[Break On This Error]This.connection.detectInitialConnect…tialConnectionDetected.bind(This));”它从FF4开始可用,文章中有一个兼容表。您可以包括MDN提供的代码片段或google提供的“ES5垫片”。
//AppController Class
var AppContoller = function(){
this.body = $("body");
var self = this;
this.init = function(){
this.connection = new ConnectionMonitor();
this.connection.detectInitialConnection( this.initialConnectionDetected );
}
//callback function I pass
this.initialConnectionDetected = function(bool){
if(bool){
trace("app connected? "+bool); // logs - "app connected? true"
self.showOnlineSwf();
}
else{
}
}
this.showOnlineSwf = function(){
trace("i'm online");
}
}