为什么我无法更新JavaScript类中ajax回调赋值的变量?
问题根源
你的代码核心问题是 .done() 回调中普通函数的 this 指向错误:普通匿名函数运行时的 this 不会指向Foo类的实例,默认指向jQuery的AJAX请求对象,严格模式下则为undefined,你此时给this.bar赋值根本不会修改类实例的属性,相当于给无关对象新增了属性,所以实例的bar始终是初始化的0。你之前对实例调用bind的用法是完全错误的,bind是用来修改函数的this指向的,不能直接作用于类实例。
修复方案
以下是三种常用的可行修复方式:
- 方案1:用箭头函数作为回调
箭头函数不会创建独立的this,会继承外层作用域的this,此处外层makeAjaxCall的this就是Foo类实例,直接使用即可:
class Foo { constructor() { this.bar = 0; this.makeAjaxCall(); } makeAjaxCall() { jQuery.get( // ajax逻辑 ) .done( (response) => { this.bar = response.bar; } ); } }
- 方案2:提前缓存实例的
this
如果要保留普通函数写法,可以在外层作用域把实例的this存到临时变量中,回调里用临时变量访问实例:
makeAjaxCall() { const self = this; // 缓存当前实例的this指向 jQuery.get( // ajax逻辑 ) .done( function(response) { self.bar = response.bar; } ); }
- 方案3:给回调函数手动绑定
this
直接给普通回调函数绑定当前实例的this指向:
makeAjaxCall() { jQuery.get( // ajax逻辑 ) .done( function(response) { this.bar = response.bar; }.bind(this) // 绑定当前实例作为回调的this ); }
完成上述修改后,只要你确认打印bax.bar的时机是在AJAX请求返回之后,就能正常拿到更新后的值。如果仍有取值问题,可进一步将依赖bar的后续逻辑放到回调内执行,或者用Promise封装AJAX请求配合async/await控制执行顺序。
内容的提问来源于stack exchange,提问作者Odai Athamneh
相关产品推荐
相关产品推荐

