在Ajax回调中访问`this`,都在Object内

我正在处理一个关于Object内部的Ajax回调的问题。 请考虑以下代码:

Search.prototype = { ask : function( query ) { // Display loader $('.loader').show(); $.ajax({ dataType : 'jsonp', type : 'GET', url : 'http://api.deezer.com/search/track/', data : { output : 'jsonp', q : query } }).done(function(res) { this.loadResults( res ); // [Error] Object success has no method 'loadResult' }); }, loadResults : function (res) { // Hide loader $('.loader').hide(); console.log( res ); // doing some stuff // ... } } var search = new Search(); search.ask( 'eminem' ); 

我得到一个错误Object success has no method loadResult ,这是有道理的,因为回调是匿名jQuery函数的一部分。

但是如何获取我的初始对象实例?

我一直在尝试使用var = this; 在Ajax调用之前,但由于同样的原因,我不会工作。

我不知道是否可以这样做,或者问题来自我的代码全球组织。 随意告诉我最佳做法:)

谢谢你提前。

[更新(已解决)]

我在代码中混淆了一些东西,虽然我没有必要在这里发帖,但我终于在我的代码中发现了问题。 对于那个很抱歉。

这是我的完整代码,现在正在运行:

 define(['jquery'], function($) { var Search = function() { this._keyDownTimer = 0; this._searchDelay = 1000; // ms }; Search.prototype = { // The init function that I though it was unnecessary to post here. Sorry :/ init : function() { $('#q').on('keydown', (function(evt) { clearTimeout( this._keyDownTimer ); this._keyDownTimer = setTimeout( (function() { this.ask( $('#q').val() ); }).bind( this ), this._searchDelay); /* <-- Here's the solution. I forgot to bind `this` to the timeout callback function, so the `this` under all of my code was referring to the anonymous function of this callback. */ }).bind( this )); }, ask : function( query ) { // Display loader $('.loader').show(); console.log(this); // Now `this` refers to my object :) var req = $.ajax({ dataType : 'jsonp', type : 'GET', url : 'http://api.deezer.com/search/track/', context : this, data : { output : 'jsonp', q : query } }); req.done(function(res) { this.loadResults(res); }); }, loadResults : function (res) { // Hide loader $('.loader').hide(); // doing some stuff // ... } }; return new Search; }); 

感谢您的回复,这真的很有帮助。

Pb解决了。

有几种方法可以做到这一点。

您可以为ajax选项设置context设置:

jQuery.ajax context设置

 $.ajax({ context: this 

Function.prototype.bind

  .done(function (res) { }.bind(this)); 

但是,这并不像……那样受到广泛支持。

jQuery.proxy

为此目的而创建。

  .done($.proxy(function (res) { }, this); 

将其分配给另一个值

 var self = this; $.ajax({ /* snip */ .done(function (res) { self.loadResults(res); 

这通常在JavaScript中完成,以便在较低的范围内访问this

箭头具有词法绑定function

 $.ajax({ /* snip */ .then(res => this.loadResults(res)); 

你可以在这里使用$ .ajax() context对象,如:

 $.ajax({ url : 'http://api.deezer.com/search/track/', context: this, ... }).done(function (res) { this.loadResults( res ); }); 

您可以使用ES5 .bind函数正确设置:

 $.ajax(...).done(this.loadResults.bind(this)); 

(使用上面链接中的垫片,或旧浏览器上的jQuery $.proxy等效项)。

或者,将context: this添加到$.ajax选项:

 $.ajax({ ..., context: this }).done(this.loadResults); 

请注意,在任何一种情况下,您都将覆盖jQuery在此中传递ajax选项对象的默认行为。

ps return $.ajax()链的结果也是一种好习惯,这样对象的用户就可以将额外的回调(例如.fail处理程序)链接到它。