【问题标题】:Javascript objects and asynchronous callsJavascript 对象和异步调用
【发布时间】:2012-03-22 17:48:14
【问题描述】:

我正在尝试使用 javascript 更面向对象的方法,并通过使用 class.prototype 实现了一个具有一些方法的类。

但是我有一个问题。

我尝试使用 myclass 中的方法作为 ajax 调用的成功函数。问题是当被 ajax 回调时,我不能使用 this 与该方法。即:

MyClass.prototype.myMethod = function(data)
{
this.data = data; /* in here this is the window object */
}
var myClass = new MyClass();
$.ajax:
    success:myClass.myMethod;

我做错了吗?

编辑:完整功能尝试

我不是

方法

    function MyClass()
{
    this.name="myclass";
};

MyClass.prototype.print = function()
{
    alert(this.name);
};

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:function(data){
            func(data);
        }
    });
};


var refreshGroups = function(groups)
{
    var myClass = new MyClass();
    myAjax(myClass,myClass.print);
    return;
}

结果:警报为空

【问题讨论】:

  • 你的意思是:$.ajax({ success:myClass.myMethod; });?
  • Javascript 不是面向对象的,所以抽象很快就中断了。 myMethod 函数不知道它只对你的类起作用,它只是一个方法。您需要将调用包装在一个匿名函数中,该函数调用您的对象上的方法。将myClass.myMethod 替换为function(){myClass.myMethod();}
  • @david JavaScript OO,它只是缺少绑定方法,因为它以一种奇怪的方式绑定this

标签: javascript oop asynchronous


【解决方案1】:

“问题是当被 ajax 回调时,我无法使用该方法。”

使用$.ajax 调用的context: 属性。

$.ajax({
    url:...,
    context: myClass,
    success: myClass.myMethod
});

或使用$.proxy...

$.ajax({
    url:...,
    success: $.proxy(myClass, 'myMethod')
});

鉴于更新后的代码,您需要将 func(data) 更改为从您使用 context: 设置的调用上下文中调用,因此您可以使用 this.func(data)...

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:function(data){
            this.func(data);
        }
    });
};

...但是由于除了调用您传递的函数并传递参数之外,您在该匿名函数中没有做任何事情,您可以只做complete:func...

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:func
    });
};

...func 的调用上下文将设置为您传递的对象,data 参数仍将传递给函数。


当然,这真的不是你的代码工作方式的问题,因为你已经有一个对你的上下文的封闭引用,所以你也可以跳过传递func,直接从你的对象...

var myAjax = function(context_) // <-- no function argument needed
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        complete:function(data){
            context_.print(data);
        }
    });
};

var refreshGroups = function(groups)
{
    var myClass = new MyClass();
    myAjax(myClass); // <--just pass the object
    return;
}

【讨论】:

  • 该死的,我需要把这个写在我的手背上什么的:-)
  • @doubter:我需要查看更多代码。您提供的内容看起来像是实际内容的一小部分。发布更多代码,我可能会提供帮助。
  • @amnotiam 更新了,如果你能看一下那就太好了:)
  • @doubter:你需要这个...complete:function(data){ this.func(data); },或者更好,就这个...complete:func。我会更新我的答案。
【解决方案2】:

JavaScript 中的方法并没有真正以任何深度方式绑定到对象属性;他们只是价值观。当您像这样引用该函数时,您在设置 ajax 调用时涉及this 的事实就完全丢失了。

有一个新的 API 可以提供帮助:

success: this.myMethod.bind(this) // or myClass.myMethod.bind(myClass) ...

.bind() 方法(来自较新浏览器中的函数原型)返回 另一个 函数,该函数将调用您的方法,确保在该调用中正确设置了 this

MDN 网站上有一个polyfill 版本的“bind”(还有其他版本)。或者,您可以明确地做同样的事情:

var obj = this;
$.ajax({
  // ...
  success: function() { obj.myMethod(); },
  // ...
});

“obj”变量是保存this 的外部上下文值所必需的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2022-11-15
    相关资源
    最近更新 更多