首页 > 其他分享 >丢失this指向问题

丢失this指向问题

时间:2022-12-07 11:14:10浏览次数:37  
标签:hours 指向 value 问题 secs let 丢失 template mins

有一个如下代码的构造器函数,我们用新语法重构一下:

function Clock({ template }) {
  
    let timer;
  
    function render() {
      let date = new Date();
  
      let hours = date.getHours();
      if (hours < 10) hours = '0' + hours;
  
      let mins = date.getMinutes();
      if (mins < 10) mins = '0' + mins;
  
      let secs = date.getSeconds();
      if (secs < 10) secs = '0' + secs;
  
      let output = template
        .replace('h', hours)
        .replace('m', mins)
        .replace('s', secs);
  
      console.log(output);
    }
  
    this.stop = function() {
      clearInterval(timer);
    };
  
    this.start = function() {
      render();
      timer = setInterval(render, 1000);
    };
  
  }
  
  let clock = new Clock({template: 'h:m:s'});
  clock.start();

重构一个版本

class Clock {
    #timer 
    #template
    constructor({ template }) {
        this.#template = template //这里的#是私有变量语法,如果浏览器不支持,去掉#就好了。对于非私有变量,上面的字段申明可以去掉
    }


    render() {
        let date = new Date();

        let hours = date.getHours();
        if (hours < 10) hours = '0' + hours;

        let mins = date.getMinutes();
        if (mins < 10) mins = '0' + mins;

        let secs = date.getSeconds();
        if (secs < 10) secs = '0' + secs;

        let output = this.#template
            .replace('h', hours)
            .replace('m', mins)
            .replace('s', secs);

        console.log(output);
    }

    stop() {
        clearInterval(this.#timer);
    };

    start() {
        this.render();
        // this.#timer = setInterval(this.render, 1000);//这么写 会有 丢失 this 的问题
        this.#timer = setInterval(()=>this.render(), 1000);
    };

}
let clock = new Clock({ template: 'h:m:s' });
clock.start();

这里我就遇到了 this丢失的问题,现象就是第一次执行是没问题的,第二次就会报错,因为 里面的this指向已经不是 Clock创建的实例了。那么,this丢失有哪些修复方式呢?
对于this丢失问题,我们有两种修复方式。我们先看底下这段代码:

class Button {
  constructor(value) {
    this.value = value;
  }

  click() {
    alert(this.value);
  }
}

let button = new Button("hello");

setTimeout(button.click, 1000); // undefined

对这段代码,我可以使用两种方式修复:
1.传递一个包装函数,例如 setTimeout(() => button.click(), 1000)。
2.将方法绑定到对象,例如在 constructor 中。


class Button {
  constructor(value) {
    this.value = value;
  }
  click = () => {
    alert(this.value);
  }
}

let button = new Button("hello");

setTimeout(button.click, 1000); // hello

类字段 click = () => {...} 是基于每一个对象被创建的,在这里对于每一个 Button 对象都有一个独立的方法,在内部都有一个指向此对象的 this。我们可以把 button.click 传递到任何地方,而且 this 的值总是正确的。

标签:hours,指向,value,问题,secs,let,丢失,template,mins
From: https://www.cnblogs.com/wzgblogs/p/16962506.html

相关文章