这是关闭的好用例吗? (对于闭包来说是新手,并试图找出如何正确使用它们的方法)

时间:2019-07-18 16:13:15

标签: javascript functional-programming closures

这个问题更多的是看我是否可以从我尝试在此处实现的“设计模式”中获得一些输入。我只是在学习JavaScript闭包,我想我已经开始了解它了。我想知道我编写此代码的方式是否质量好-您希望在生产代码中看到这种东西,或者至少有些“拼凑在一起”的东西。显然对任何批评开放-在这里学习。

有问题的代码正试图回答JavaScript中提出的挑战:Front Masters上的Hard部分(由Will Sentance撰写)。基于挑战,似乎我超越了要求,因为所提供的解决方案在运行时无法正常工作。

挑战:

  

编写一个函数changeColor,该函数在被调用时将首先检查是否   当前页面背景颜色为“ rgb(221,238,255)”。如果是的话   将颜色更改为“ rgb(255,238,221)”。如果不是,它将设置   颜色改为“ rgb(221,238,255)”。

     

将点击事件监听器添加到上方的按钮#1(其ID为   “启用”)。单击后,该按钮应登录到控制台   1“。它还应该在按钮#2(ID为“ color”)上设置点击事件监听器。该监听器应登录控制台“ clicked 2”,然后   调用刚刚创建的changeColor函数。

     

清除控制台,然后点击“使用JS运行”按钮。看什么代码   通过分析控制台来运行。然后尝试更改背景   单击按钮#2进行颜色显示。该按钮需要发生什么   工作吗?

基于挑战的措辞,似乎暗示的解决方案是(使用伪ish代码):

activationButton.addEventListener("click", () => {
  console.log("clicked activation button")
  colorChangerButton.addEventListener("click", () => {
    console.log("clicked color changer button")
    changeTheColor()
  })
})

上述代码的明显问题是,每次您单击colorChangerButton时,都会将一个新的事件侦听器添加到activationButton中。在这里,我开始考虑尝试使用闭包来跟踪状态变量,以便可以确保将事件侦听器仅添加到第二个按钮一次。同样,这是解决方案集中提供的解决方案。

为此,这就是我想出的(请假设那里有正确的HTML等):

(function () {

  let clickCount = 0

  function changeColor() {
    if (document.body.style.backgroundColor === "rgb(221, 238, 255)") {
      document.body.style.backgroundColor = "rgb(255, 238, 221)"
    } else {
      document.body.style.backgroundColor = "rgb(221, 238, 255)"
    }
  }

  function activateButton2() {
    const btn2 = document.querySelector('#color')
    btn2.addEventListener("click", () => {
      console.log("clicked #2")
      changeColor()
    })
  }

  const btn1 = document.querySelector('#activate')
  btn1.addEventListener("click", () => {
    clickCount++
    if (clickCount === 1) {
      activateButton2()
    } 
    console.log("clicked #1")
    return
  })

  return {
    changeColor: changeColor,
    activateButton2: activateButton2
  }
})()

这是我期望的那样工作-颜色更改功能和控制台日志正在按我期望的方式触发。

我的一个问题是关于将按钮变量包含在IIFE中。我觉得我看到很多前端脚本都将所有查询选择器放在脚本顶部–与将它们包括在这样的函数中相比,有理由这样做吗?如果我正确地理解了闭包,那么一旦创建了事件处理程序,就会对IIFE中的所有内容进行持久引用,因此我可以触发此函数,并且按钮及其处理程序将继续存在并按预期运行。

似乎我也可以使用布尔值来跟踪第一个按钮的“单击”状态,并使用switch语句来检查页面的背景色。

任何人想提供的其他指针吗?预先感谢您的浏览。

0 个答案:

没有答案
相关问题