JavaScript中onloadend方法内reader对象未定义问题咨询
问题原因与解决方法
问题根源
JavaScript中的this绑定规则和你熟悉的C++/Java/Python不同,它的指向并非固定绑定到类实例,而是由函数的调用方式决定:
- 当你把
this.complexProcess直接赋值给this.reader.onloadend时,这个函数就脱离了CustomReader实例的上下文。 - 当
FileReader触发onloadend事件时,会以自身作为this来调用回调函数,此时complexProcess里的this指向的是FileReader实例,而非你的CustomReader实例,自然找不到this.reader属性。
解决方法
以下三种常用方式可修正这个this绑定问题:
1. 使用箭头函数继承上下文
箭头函数不会创建自身的this,会直接继承外层作用域的this(即CustomReader实例):
class CustomReader{ constructor(){ this.reader = new FileReader() this.customFunc = {} } read(file, customFunc){ this.customFunc = customFunc; this.reader.onloadend = () => this.complexProcess(); this.reader.readAsText(file); } complexProcess( ) { console.log(this.reader) // 正确指向CustomReader的reader实例 this.customFunc(this.reader.result) // 可正常获取文件内容 } }
2. 使用bind()强制绑定this
bind()方法会返回一个新函数,强制将函数的this绑定到指定对象,推荐在构造函数中提前绑定,避免重复创建函数:
class CustomReader{ constructor(){ this.reader = new FileReader() this.customFunc = {} this.complexProcess = this.complexProcess.bind(this); } read(file, customFunc){ this.customFunc = customFunc; this.reader.onloadend = this.complexProcess; this.reader.readAsText(file); } complexProcess( ) { console.log(this.reader) this.customFunc(this.reader.result) } }
3. 通过闭包保存实例引用
在read方法中用变量保存当前实例,回调中直接引用该变量:
class CustomReader{ constructor(){ this.reader = new FileReader() this.customFunc = {} } read(file, customFunc){ this.customFunc = customFunc; const self = this; this.reader.onloadend = function() { console.log(self.reader) // 直接通过self访问CustomReader实例 self.customFunc(self.reader.result) }; this.reader.readAsText(file); } complexProcess( ) { console.log(this.reader) this.customFunc(this.reader.result) } }
内容的提问来源于stack exchange,提问作者Counlin
相关产品推荐
相关产品推荐

