亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

有沒有辦法使用命名箭頭函數來維護對象內的詞法范圍?

有沒有辦法使用命名箭頭函數來維護對象內的詞法范圍?

郎朗坤 2022-09-23 10:07:37
描述: 我正在使用并希望調用一個命名函數(不是匿名函數),因為我希望能夠在以后的階段使用 removeEventListener。但是,事件處理程序(即箭頭函數)的內部顯示“this”仍指向窗口對象而不是游戲對象。window.addEventListener()console.logPS:在我重構這個時忽略代碼的其他部分,其余的可能仍然不完整,我知道我可以使用構造函數,但我處于學習階段,在我研究構造函數之前,我想看看是否可以在沒有構造函數的情況下完成此操作function makeGameObject() {  return {    score: 0,    level: 1,    start() {      for (let coin of coins) {        this.moveCoin(coin);      }      window.addEventListener("keydown", this.gameOn)    },    stop() {      window.removeEventListener("keydown", this.gameOn);    },    gameOn: (evt) => {      console.log(this);      if (evt.key.toUpperCase() === "W" || evt.key === "ArrowUp") {        this.moveObject(player, 30, 'up');      } else if (evt.key.toUpperCase() === "S" || evt.key === "ArrowDown") {        this.moveObject(player, 30, 'down');      } else if (evt.key.toUpperCase() === "A" || evt.key === "ArrowLeft") {        this.moveObject(player, 30, 'left');        player.style.transform = 'scale(-1,1)';      } else if (evt.key.toUpperCase() === "D" || evt.key === "ArrowRight") {        this.moveObject(player, 30, 'right');        player.style.transform = 'scale(1,1)';      }      for (let coin of coins) {        if (this.isTouching(player, coin)) {          this.moveCoin(coin);          score++;          h1.innerText = score;        }      }    },下面是對函數的調用:const player = document.querySelector("#player");const coins = document.querySelectorAll(".coin");const body = document.querySelector("body");const h1 = document.querySelector("h1");const game = makeGameObject();game.start();
查看完整描述

1 回答

?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

一種方法是動態創建 的綁定版本并改用它:gameOn()


{

  // ...


  start() {

    for (let coin of coins) {

      this.moveCoin(coin);

    }

    if (this.boundGameOn === undefined) {

      this.boundGameOn = this.gameOn.bind(this);

    }

    window.addEventListener("keydown", this.boundGameOn)

  },


  stop() {

    window.removeEventListener("keydown", this.boundGameOn);

  },


  // ...

}

理想情況下,您會在構造函數中執行此操作。如果你有一個構造函數而不是一個對象文本,你可以這樣做:


function GameObject () {

  this.boundGameOn = this.gameOn.bind(this)

}


GameObject.prototype = {

  // rest of code ..

}

事實上,在 React 應用程序中,看到這種設計模式并不少見:


function GameObject () {

  this.gameOn = this.gameOn.bind(this); // MAGIC!!

}


GameObject.prototype = {

  // ...


  start() {

    for (let coin of coins) {

      this.moveCoin(coin);

    }

    window.addEventListener("keydown", this.gameOn)

  },


  stop() {

    window.removeEventListener("keydown", this.gameOn);

  },


  // ...

}

MAGIC 行確保內部始終指向游戲對象,因為您正在用其自身的綁定版本覆蓋它。thisgameOn()


這在ES6類語法中看起來稍微干凈一些(只是稍微有點,我個人對這兩種語法都沒有偏好):


class GameObject {


  constructor () {

    this.gameOn = this.gameOn.bind(this); // MAGIC!!

  }


  // ...


  start() {

    for (let coin of coins) {

      this.moveCoin(coin);

    }

    window.addEventListener("keydown", this.gameOn)

  }


  stop() {

    window.removeEventListener("keydown", this.gameOn);

  }


  // ...

}

使用為ES7提出的實驗性類屬性語法,它甚至更簡單:你可以只使用箭頭函數(現在不要直接使用它,2020年中期,因為Safari不支持這個,但如果你使用Babel或Typescript,你可以編譯到ES6):


class GameObject {

  // ...


  start = () => {

    for (let coin of coins) {

      this.moveCoin(coin);

    }

    window.addEventListener("keydown", this.gameOn)

  }


  stop = () => {

    window.removeEventListener("keydown", this.gameOn);

  }


  // ...

}

在本例中由箭頭函數綁定。this


查看完整回答
反對 回復 2022-09-23
  • 1 回答
  • 0 關注
  • 98 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號