TypeScript嵌套函数访问全局变量报读取user属性undefined错误
报错原因
这是JavaScript/TypeScript中典型的this上下文丢失问题:
- 你在
then、catch中传入的是普通function声明的回调函数,这类函数运行时会生成独立的this绑定,不会继承外层mark_paid方法的this上下文,严格模式下回调内部的this值为undefined - 当代码尝试读取
undefined.user时,就会抛出你看到的Cannot read properties of undefined (reading 'user')错误 - 额外注意:你的代码还有一处逻辑笔误,
username: this.token.username和前面token:this.user.token的取值逻辑矛盾,正常用户名应该和token同属user对象下的属性,就算修复了this指向,这里不修改也会触发新的报错。
修复方案
最推荐使用箭头函数修复,箭头函数不会生成独立的this上下文,会直接继承外层作用域的this,写法最简洁,也是目前TS项目的通用实践:
把所有then、catch中的普通函数回调替换为箭头函数,同时修正笔误,修改后的完整代码如下:
mark_paid(id: any) { Swal.fire ({ title: 'Are you sure?', text: "You must ensure that you have sent the money first before clicking this button. Providing false information or coinlocking will cause your account to be banned", icon: 'warning', showCancelButton: true, confirmButtonColor: '#7367F0', cancelButtonColor: '#E42728', confirmButtonText: 'Yes, ive sent it', customClass: { confirmButton: 'btn btn-primary', cancelButton: 'btn btn-danger ml-1' } }).then((result) => { if (result.value) { const headerDict = { 'Content-Type': 'application/json', Accept: 'application/json', token: this.user.token, // 修正笔误,原代码this.token为错误取值路径 username: this.user.username } const requestOptions = { headers: new Headers(headerDict), }; return fetch('https://some.endponint.com/markPaid/'+id,requestOptions) .then((response) => { console.log(response); if (!response.ok) { throw new Error(response.statusText); }else{ Swal.fire({ title: 'Trade Marked as Paid', text: 'The seller will check on your payment and send the BTC shortly', icon: 'success', customClass: { confirmButton: 'btn btn-success' } }); location.reload(); } return response.json(); }) .catch((error) => { Swal.fire({ title: 'Ops', text: 'An error happened please try again', icon: 'error', customClass: { confirmButton: 'btn btn-success' } }); }); } }); }
其他可选修复方式
如果你不想使用箭头函数,也可以选择以下两种方案:
- 提前缓存外层
this:在调用Swal.fire之前先声明const _this = this,后续所有回调中需要访问实例属性时,把this替换为_this即可 - 手动绑定
this:给每个普通回调末尾追加.bind(this),比如.then(function(result){ /* 业务逻辑 */ }.bind(this)),这种写法冗余度高,日常开发不推荐使用。
内容的提问来源于stack exchange,提问作者Brian Kiplagat
相关产品推荐
相关产品推荐

