javascript - 我的闭包示例没有像我想的那样工作

标签 javascript closures

我试图弄清楚闭包并创建了这个简单的示例,您在其中调用带有名称的函数 greet 并且在第一次调用后问候语应包含先前给定的名称。

因此,如果您调用 greet('Andrew') 和 greet('Joseph'),我希望在控制台上看到:

Hello Andrew
Hello Andrew, Joseph 

这是我的代码: https://codepen.io/anon/pen/pVpBdy

let greet = function(name) {
    let greeting = 'Hello ';

    let updateGreet = function() {
      greeting = greeting + ', ' + name; 
    }

    let printGreet = function() {
      console.log(greeting + name);
      updateGreet();
    }

    return printGreet();
} 

greet('Andrew');
greet('Joseph');

我看到的结果是:

Hello Andrew
Hello Joseph 

似乎每次我调用 greet() 时都会重新初始化问候语,我不知道为什么。

请帮助我理解这一点。

最佳答案

您当前的 greet 可以被调用以创建 一个独立的对象 - 对象 然后存储名称。当前每次调用 greet 时,您都在创建一个单独的 greeting 变量,封装在不同的对象中。

最简单的方法是立即执行函数,这样所有对 greet 的调用都将引用同一个对象。

您还应该将 name 变量传递给 updateGreet:

const greet = (() => {
  let greeting = 'Hello';
  const updateGreet = function(name) {
    greeting = greeting + ', ' + name;
  }
  const printGreet = function(name) {
    console.log(greeting + ', ' + name);
    updateGreet(name);
  }
  return printGreet;
})();

greet('Andrew');
greet('Joseph');
greet('Bob');

此外,无论何时声明其引用不会更改的变量,都要确保使用 const - 它使代码更易于理解(对您和其他人而言)。

关于javascript - 我的闭包示例没有像我想的那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50243323/

相关文章:

javascript - 使用闭包来模拟封装是个坏主意吗?

javascript - Dart 相当于匿名闭包

Javascript——带有简单加法器函数的闭包

swift - 如何在移动到另一个 VC 之前预加载数据

Ruby Pascal 的带内存的三角形生成器

javascript - 如何检查javascript对象内部的内容

javascript - jQuery Validate() 和 Valid() 方法未定义或不起作用

javascript - 如何将默认的 leaflet.control 替换为一组单独的按钮

javascript - 如何在 Angular 中访问表单元素的 $valid ?

javascript - 验证由 JavaScript 生成的动态 HTML