【问题标题】:Closures in Javascript - beginner questionJavascript中的闭包 - 初学者问题
【发布时间】:2020-08-30 07:10:14
【问题描述】:

我阅读了无数关于闭包的文章,但我仍在为此苦苦挣扎。也许有人可以向我解释,为什么该功能无法按预期工作。

let counter = (key) => {
  let counter = 10;
  if (key === 'milk') {
    ++counter;
  }
  if (key === 'bread') {
    --counter;
  }
  return function() {
    console.log(counter)
  }
}

let shopping = counter();
shopping('milk'); //  why not 11
shopping('milk'); //  12
shopping('bread'); //  11 
shopping('bread'); //  10

对我来说,它应该始终根据参数增加或减少计数器,因为当前状态(计数器)保存在购物变量中。但是,现在的输出始终是 10。

【问题讨论】:

  • 首先 key 参数应该属于返回的函数而不是更高级别的函数以及条件和递增和递减

标签: javascript closures


【解决方案1】:
 let shopping = counter();

您调用 counter 并且不传递任何参数。 key 未定义。 if 语句均未触发。

 shopping('milk');

您调用shopping,这是counter 返回的函数,如下所示:

function(){
    console.log(counter)
}

当你向它传递一个参数时,它不会对它做任何事情。它只是记录计数器的当前值。


闭包的唯一用途是保护counter 变量。

该函数所做的所有其他事情都是您需要运行的逻辑每次返回的函数被调用,所以其他所有事情都应该在该返回的函数中。

let counter = () => {
  let counter = 10;

  return function(key) {
    if (key === 'milk') {
      ++counter;
    }
    if (key === 'bread') {
      --counter;
    }
    console.log(counter)
  }
}

let shopping = counter();
shopping('milk');
shopping('milk');
shopping('bread');
shopping('bread');

【讨论】:

    【解决方案2】:

    从您调用shopping 的方式来看,您似乎想向它传递一个参数,并且希望计数器变量被它改变。

    问题是,你已经在外部函数上实现了这个逻辑,而不是在 returned 函数上实现它。

    因此,要让它按您的意愿工作,您需要移动 returned 函数内的参数和逻辑:

    let counter = () => {
      let counter = 10;
    
      return function(key) {
        if (key === 'milk') {
          ++counter;
        }
        if (key === 'bread') {
          --counter;
        }
        console.log(counter);
      }
    }
    
    let shopping = counter();
    shopping('milk');
    shopping('milk');
    shopping('bread');
    shopping('bread');

    备注:通过为两个不同的变量赋予相同的名称:counter,您使事情更难以解释。当您选择不同的名称时,可读性会提高。

    【讨论】:

      【解决方案3】:

      首先key参数应该属于返回的函数而不是更高级别的函数以及递增和递减的条件

      let counter = () => {
          let counter = 10;
          return function(key) {
              if(key === 'milk') {
                  ++counter;
              } else if(key === 'bread') {
                  --counter;
              }
              console.log(counter);
          }
      }
      
      let shopping = counter();
      shopping('milk');           //  11
      shopping('milk');           //  12
      shopping('bread');          //  11 
      shopping('bread');          //  10

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-24
        • 1970-01-01
        • 2021-02-13
        • 2021-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-13
        相关资源
        最近更新 更多