使用回调处理程序调用函数内部的父对象方法
Call parent object method inside function with callback handler
我正在调用ParentObject.doSomething(),它通过inturn调用WebService对象来执行一些ajax调用,一旦ajax调用成功,就会执行回调函数。但是回调函数中的任何父函数都会失败。
我认为这与范围决议有关。我找不到解决这个问题的方法。
有没有更好的架构风格来模块化ajax服务和模型?
我还创建了一个jsfiddle-http://jsfiddle.net/bzKXr/2/
var ParentObject = {
doSomething: function(){
document.write("Inside doSomething <br />");
var self = this;
WebServices.firstService("some URL", self.successCallback);
},
changeData: function(data){
//Manipulate data
document.write("Inside changeData <br />");
},
successCallback: function(jsonData){
document.write("Inside successCallback <br />");
try {
//Execution fails at this point. Possibly because of scope resolution
this.changeData(jsonData);
}
catch (error) {
console.log(error);
document.write(error);
}
},
};
var WebServices = {
firstService: function(url, successCallbackHandler){
document.write("Inside firstService <br />");
//Get data using the URL
//on success call successCallback
successCallbackHandler("some data");
}
};
$(document).ready(function() {
ParentObject.doSomething();
});
编写self.successCallback
并没有将函数绑定到self
,您实际上必须将函数调用为self.successCallback()
才能正确绑定上下文。
您可以通过将调用封装在一个闭包中来轻松完成这一操作,该闭包保留对self
:的访问权限
doSomething: function(){
document.write("Inside doSomething <br />");
var self = this;
WebServices.firstService("some URL", function() {
self.successCallback();
});
},
或者在ES5中,可以使用.bind()
,确保successCallback
的this
上下文始终是指定的参数:
doSomething: function(){
document.write("Inside doSomething <br />");
WebServices.firstService("some URL", this.successCallback.bind(this));
},
这里有最漂亮的方法:
WebServices.firstService("some URL", this.successCallback.bind( this ));
但是,它不是跨浏览器的。(阅读:IE8及以下版本无法使用)
这就是为什么jQuery有$.proxy
:
WebServices.firstService("some URL", $.proxy( this.successCallback, this ));
调用回调函数时,this
无效。在javascript中,如果用foo.bar()
调用函数,则this
将被设置为foo
,但如果您只调用foo()
,则会保留先前设置的this
,在您的情况下,可能是事件的元素WebService
。为了避免这种情况,您必须使用闭包。您可以将this.changeData(jsonData);
替换为ParentObject.changeData(jsonData);
。闭包意味着函数可以访问定义函数的范围中的变量,因此函数可以访问ParenObject。
一种更优雅的方式可能是:
var ParentObject = {
doSomething: function(){
document.write("Inside doSomething <br />");
var self = this;
WebServices.firstService("some URL", function(jsonData) {
document.write("Inside successCallback <br />");
self.changeData(jsonData);
}
},
changeData: function(data){
//Manipulate data
document.write("Inside changeData <br />");
}
};
回调函数是直接在doSomething
函数中定义的,因此您可以访问其中定义的变量self
,并可以调用self.changeData()
。
另一种可能性是更改
WebServices.firstService("some URL", self.successCallback);
至
WebServices.firstService("some URL", function(data){ return self.successCallback(data) });
基本问题是,与Python不同,Javascript中的方法Javascript在将它们传递到其他地方或设置另一个变量时就会忘记它们的所有者对象。
如果将this.changeData(jsonData);
更改为ParentObject.changeData(jsonData);
,它应该可以工作。
错误的原因是,当AJAX调用返回时,this
变量不再引用ParentObject
。
另一种方法是将对this
的引用存储在另一个变量中(按照惯例称为that
),并将代码更改为that.changeData(jsonData);
- 如何使用内部对象构造对象
- 这个 getter-setter 闭包是否有充分的理由以这种方式在其内部对象中声明它是私有的
- 为什么这个内部对象文字等于另一个对象
- 内部对象如何在声明时引用其父对象的对象
- 将角度对象函数调用传播到内部对象
- Javascript 变量范围.如何从内部对象函数访问对象变量
- 更改此内部对象的行为
- "node-r包.json“-如何访问内部对象
- 在使用es2015时,我们应该如何获得对函数内部对象的引用
- 使用“;这个“;internal$.each内部对象方法
- '这'ES6中的内部对象文字
- 访问对象内部对象的属性
- 当数组是服务内部对象的属性时,如何在页面上逐个显示数组元素
- 用循环将内部对象附加到多维数组中
- 从内部对象javascript设置字段值
- 外部文件与内部对象的GeoJSON投影
- 如何在javascript对象中访问内部对象的属性
- 调用内部对象函数javascript
- Javascript函数内部对象的不同
- “this"内部对象