1. 程式人生 > >記一個在js中使用setTimeout方法踩的坑(箭頭函式與function定義的區別)

記一個在js中使用setTimeout方法踩的坑(箭頭函式與function定義的區別)

今天寫程式碼時遇到了一個問題,程式碼如下

      this.timer = setTimeout(function() {
        const result = []
        for (let i in this.cities) {
          this.cities[i].forEach((value) => {
            if (value.spell.indexOf(this.keyword) > -1 || value.name.indexOf(this.keyword) > -1) {
              result.push(value)
            }
          })
        }
        console.log(this.cities)
        this.list = result
      }, 100)

其中最主要的問題就是倒數第三行程式碼輸出的是undefined(在方法外輸出確實有值)

經過一番排錯後發現,是ES6的箭頭函式() => {}function(){}定義的方法中,this的指向有問題

使用function定義的函式,this的指向隨著呼叫環境的變化而變化的,而箭頭函式中的this指向是固定不變的,一直指向的是定義函式的環境。

因此我上面的方法

 

解決方案:

把使用function的地方改掉,改用箭頭函式的方式來定義,可以正常輸出,如下:

      this.timer = setTimeout(() => {
        const result = []
        for (let i in this.cities) {
          this.cities[i].forEach((value) => {
            if (value.spell.indexOf(this.keyword) > -1 || value.name.indexOf(this.keyword) > -1) {
              result.push(value)
            }
          })
        }
        console.log(this.cities)
        this.list = result
      }, 100)

或者,將函式內的this固定,如下定義一個const that = this   :

      const that = this
      this.timer = setTimeout(function() {
        const result = []
        for (let i in that.cities) {
          that.cities[i].forEach((value) => {
            if (value.spell.indexOf(that.keyword) > -1 || value.name.indexOf(that.keyword) > -1) {
              result.push(value)
            }
          })
        }
        console.log(that.cities)
        that.list = result
      }, 100)

都可以完美實現

=。=這bug嚇死我了,我還以為我前面都寫錯了。。。(畢竟我也