匿名函数中全局变量使用问题:file.ts事件触发赋值undefined解决
解决匿名函数中全局/实例变量赋值undefined的问题
这个问题我之前也碰到过,核心就是this的上下文绑定搞的鬼!你之所以能打印出e.target.result但赋值后this.imageStringBase64变成undefined,是因为匿名回调函数里的this已经不是你定义变量时的那个上下文了。
问题根源
用function关键字定义的匿名函数会绑定自己的this,在FileReader的onload回调里,这个this指向的是reader实例本身,而不是你定义imageStringBase64的全局环境或类实例。所以你其实是给reader对象加了个imageStringBase64属性,而你原本的变量根本没被修改,自然还是undefined。
三种解决办法
1. 使用箭头函数(最推荐,现代TS/JS首选)
箭头函数不会创建自己的this,它会继承外层作用域的this,完美解决上下文丢失问题:
// 假设你的代码结构大概是这样 const fileInput = document.getElementById('file-input') as HTMLInputElement; // 如果是类组件的话,this指向类实例 this.imageStringBase64 = ''; fileInput.addEventListener('change', (e) => { const file = (e.target as HTMLInputElement).files?.[0]; if (!file) return; const reader = new FileReader(); // 这里用箭头函数,this会继承外层的上下文 reader.onload = (loadEvent) => { const base64Str = loadEvent.target?.result as string; console.log(base64Str); // 正常打印 this.imageStringBase64 = base64Str; // 现在this指向正确的上下文 }; reader.readAsDataURL(file); });
2. 提前保存上下文到变量
如果因为环境限制不能用箭头函数,在外层把this存成一个变量(比如self或that),然后在回调里用这个变量:
fileInput.addEventListener('change', function(e) { const self = this; // 保存当前正确的上下文 const file = (e.target as HTMLInputElement).files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(loadEvent) { const base64Str = loadEvent.target?.result as string; self.imageStringBase64 = base64Str; // 用self代替this,指向原来的上下文 }; reader.readAsDataURL(file); });
3. 使用bind()绑定this
通过Function.prototype.bind()方法,把回调函数的this强制绑定到外层的上下文:
fileInput.addEventListener('change', function(e) { const file = (e.target as HTMLInputElement).files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(loadEvent) { const base64Str = loadEvent.target?.result as string; this.imageStringBase64 = base64Str; }.bind(this); // 绑定外层的this到当前回调函数 reader.readAsDataURL(file); });
选第一种箭头函数的方式就好,代码更简洁,也符合现代TS/JS的写法习惯~
内容的提问来源于stack exchange,提问作者Walter White
相关产品推荐
相关产品推荐

