解决js类定义里面绑定事件this指向问题
问题分析
最近一个js问题困扰了2小时:现在我们需要定义一个类,类里面初始化对象时会绑定事件,然后销毁方法会解绑事件,精简代码如下:(这里使用es6定义类的方式,使用原始的function思路也是一样的)
class Test {
  constructor() {
    this.width = 0;
  }
  //初始化对象时使window绑定事件resize,设置对象宽度
  init(){
    window.addEventListener("resize",this.resize);
  }
  
  //销毁方法,解绑事件
  destroy(){
    window.removeEventListener("resize",this.resize);
  }
  
  //监测window宽度变化,复值给对象的width属性
  resize(){
    console.log(this);
    this.width = document.body.clientWidth;
  }
}
//创建并初始化对象
let test = new Test;
test.init();
已知问题:根据事件绑定中,谁调用,this就指向谁,得知resize中的this其实是指向window,不能实现我们需要的效果,这个比较容易理解。
 已知限制:
- 1、在不改变this指向情况下,resize函数里面的this永远指向调用它的window
- 2、绑定事件和解绑事件中第二个参数必须是同一个函数引用
- 3、因为绑定事件和解绑事件中第二个参数必须是同一个函数引用,所以不能直接传参数
因为上面的3个限制,所以想了很多中方法都失败告终,最终还是必须使用bind方法改变this指向,同时存储bind方法返回的匿名函数,然后再传给事件绑定方法。
ps:js的bind方法能改变this指向,并返回一个新的匿名函数,但不会执行函数。例如:this.resize.bind(this)
解决代码
详细说明请看注释
class Test {
  constructor() {
    this.width = 0;
    this.newResize = null; //此属性用于保存bind返回的匿名函数
  }
  
  //初始化对象时使window绑定事件resize,设置对象宽度
  init(){
    //使用bind改变this指向,并保存返回的匿名函数
    this.newResize = this.resize.bind(this);
    window.addEventListener("resize",this.newResize )
  }
  
  //销毁,解绑事件
  destroy(){
    window.removeEventListener("resize",this.newResize );
  }
  
  //监测window宽度变化,复值给对象的width属性
  resize(){
    console.log(this);
    this.width = document.body.clientWidth;
  }
}
let test = new Test;
test.init();
如果解决了你的问题,点个赞 ^_^
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号