Javascript 回调的范围问题
我在使回调函数正常工作时遇到一些问题。这是我的代码:
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall("read_some_data", { }, this.readSuccess, this.readFail);
}
SomeObject.prototype.readSuccess = function(response)
{
this.data = response;
this.someList = [];
for (var i = 0; i < this.data.length; i++)
{
var systemData = this.data[i];
var system = new SomeSystem(systemData);
this.someList.push(system);
}
this.refreshList();
}
基本上 SomeAjaxCall 正在发出 ajax 数据请求。如果成功,我们使用回调“this.readSuccess”,如果失败,则使用“this.readFail”。
我发现 SomeObject.readSuccess 中的“this”是全局 this(又名窗口对象),因为我的回调被作为函数而不是成员方法调用。我的理解是,我需要使用闭包来保留“this”,但是,我无法让它发挥作用。
如果有人能够告诉我我应该做什么,我将不胜感激。我仍然在思考闭包是如何工作的,特别是在这种情况下它们将如何工作。
谢谢!
I am having some trouble getting a callback function to work. Here is my code:
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall("read_some_data", { }, this.readSuccess, this.readFail);
}
SomeObject.prototype.readSuccess = function(response)
{
this.data = response;
this.someList = [];
for (var i = 0; i < this.data.length; i++)
{
var systemData = this.data[i];
var system = new SomeSystem(systemData);
this.someList.push(system);
}
this.refreshList();
}
Basically SomeAjaxCall is making an ajax request for data. If it works we use the callback 'this.readSuccess' and if it fails 'this.readFail'.
I have figured out that 'this' in the SomeObject.readSuccess is the global this (aka the window object) because my callbacks are being called as functions and not member methods. My understanding is that I need to use closures to keep the 'this' around, however, I have not been able to get this to work.
If someone is able show me what I should be doing I would appreciate it greatly. I am still wrapping my head around how closures work and specifically how they would work in this situation.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最简单的做法就是将“this.readSuccess”包装在另一个函数中:
一些 Javascript 框架提供了一个实用程序来将函数“绑定”到对象,这意味着它会为您创建其中一个小函数。请注意,变量“obj”将被这些小函数“记住”,因此当调用处理程序时,“this”引用将指向用于调用“refreshData”的对象。
Well the most straightforward thing to do is to just wrap "this.readSuccess" in another function:
Some Javascript frameworks provide a utility to "bind" a function to an object, which simply means that it creates one of those little functions for you. Note that the variable "obj" will be "remembered" by those little functions, so when your handlers are called the "this" reference will be to the object that was used to call "refreshData".
您这里的问题不完全是闭包或范围界定问题。问题在于,当您将
this.readSuccess
分配给变量时,您分配了函数本身,而没有任何其原始所属对象的概念。以同样的方式,您可以采用常规的“独立”函数并将其用作对象的方法:
并且您的问题可以在本示例中复制
所以您的问题是将 this.readSuccess 分配给某个变量 并将其作为 this 的方法调用。这可以通过 Pointy 演示的闭包来完成。由于我不知道“SomeAjaxCall”实际上做了什么,因此很难知道
this
的值是否实际上丢失以及var obj = this
是否确实需要。很可能不是,所以您可以使用这种代码:在您的情况下,这将是(编辑:添加传递给处理程序的参数):
如前所述,几个 js 框架提供一个
bind
函数来简化此类问题。但您并不需要为此建立一个完整的框架:这里有一个完美的Function#bind
方法,可以使用普通的 javascript 运行:在
Function#bind
的帮助下,你可以写:Your problem here is not exactly a closure or scoping problem. The problem is that when you assign
this.readSuccess
to a variable, you assign the function itself without any notion of the object it originaly belongs to.In the same way, you can take a regular, "stand-alone" function and use it as method of an object:
And your problem can be replicated in this example
So your problem is to assign this.readSuccess to some variable and having it called as a method of this. Which can be done with a closure as demonstrated by Pointy. Since I don't know what "SomeAjaxCall" actually does, it's hard to know if the value of
this
is actually lost and ifvar obj = this
is actually needed. Chances are that it's not, so you can be fine with this kind of code:In your case, that would be (edit: adding the arguments passed to the handler) :
As noted previously, several js frameworks offer a
bind
function to simplify this kind of issue. But you don't need a complete framework just for this : here is a perfectly fineFunction#bind
method that works an plain javascript:With the help of
Function#bind
, you can write:以下站点似乎表明问题可能更多地出在您的“类”建筑中,而不是使用中。如果您仔细阅读“使用原型属性重写”,他们会写到“类”结构的特定方法将使方法保持全局而不是基于实例。也许另一种创作方法?
http://devedge-temp.mozilla.org/viewsource/2001/oop -javascript/
The following site seems to suggest that the problem may be more in your "class" building than in the usage. If you read down to the "rewrite using prototype properties", they write that that particular method of "class" structuring will keep the methods global instead of instance-based. Perhaps another creation method?
http://devedge-temp.mozilla.org/viewsource/2001/oop-javascript/