我正在尽最大努力理解JavaScript闭包。

通过返回一个内部函数,它可以访问直接父函数中定义的任何变量。

这对我有什么用?也许我还没完全搞清楚。我在网上看到的大多数示例都没有提供任何真实的代码,只是一些模糊的示例。

有人能告诉我一个闭包的真实用法吗?

比如这个吗?

var warnUser = function (msg) {
    var calledCount = 0;
    return function() {
       calledCount++;
       alert(msg + '\nYou have been warned ' + calledCount + ' times.');
    };
};

var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();

当前回答

你举的例子很好。闭包是一种抽象机制,允许您非常清晰地分离关注点。您的示例是将插装(计数调用)与语义(错误报告API)分离的例子。其他用途包括:

Passing parameterised behaviour into an algorithm (classic higher-order programming): function proximity_sort(arr, midpoint) { arr.sort(function(a, b) { a -= midpoint; b -= midpoint; return a*a - b*b; }); } Simulating object oriented programming: function counter() { var a = 0; return { inc: function() { ++a; }, dec: function() { --a; }, get: function() { return a; }, reset: function() { a = 0; } } } Implementing exotic flow control, such as jQuery's Event handling and AJAX APIs.

其他回答

JavaScript模块模式使用闭包。它的良好模式允许你拥有类似“公共”和“私有”变量的东西。

var myNamespace = (function () {

  var myPrivateVar, myPrivateMethod;

  // A private counter variable
  myPrivateVar = 0;

  // A private function which logs any arguments
  myPrivateMethod = function(foo) {
      console.log(foo);
  };

  return {

    // A public variable
    myPublicVar: "foo",

    // A public function utilizing privates
    myPublicFunction: function(bar) {

      // Increment our private counter
      myPrivateVar++;

      // Call our private method using bar
      myPrivateMethod(bar);
    }
  };

})();

闭包有各种各样的用例。在这里,我将解释闭包概念的最重要的用法。

闭包可以用来创建私有方法和变量,就像面向对象的语言,如java、c++等。一旦你实现了私有方法和变量,你在函数中定义的变量将不能被窗口对象访问。这有助于数据隐藏和数据安全。

const privateClass = () => {
  let name = "sundar";
  function setName(changeName) {
    name = changeName;
  }
  function getName() {
    return name;
  }
  return {
    setName: setName,
    getName: getName,
  };
};

let javaLikeObject = privateClass(); \\ similar to new Class() in OOPS.

console.log(javaLikeObject.getName()); \\this will give sundar
javaLikeObject.setName("suresh");
console.log(javaLikeObject.getName()); \\this will give suresh

另一个关于闭包的现实例子:

创建index . html:

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Program with Javascript</title>
  </head>
  <body>
    <p id="first"></p>
    <p id="second"></p>
    <button onclick="applyingConcepts()">Click</button>
    <script src="./index.js"></script>
  </body>
</html>

2)在index.js:

  let count = 0;
  return () => {
    document.getElementById("first").innerHTML = count++;
  };
})();

在本例中,当您单击一个按钮时,计数将在p#id上更新。 注意:您可能想知道这段代码有什么特别之处。检查时,您将注意到不能使用window对象更改count的值。这意味着你已经声明了私有变量count,这样可以防止你的状态被客户端破坏。

闭包是一种创建生成器的有用方法,它是一个按需递增的序列:

var foobar = function(i){var count = count || i; return function(){return ++count;}} 巴兹 = 福巴(1); console.log(“First Call: ” + baz());2 console.log(“第二次调用: ” + baz());3

区别总结如下:

Anonymous functions                                    Defined functions

Cannot be used as a method                             Can be used as a method of an object

Exists only in the scope in which it is defined        Exists within the object it is defined in

Can only be called in the scope in which it is defined Can be called at any point in the code

Can be reassigned a new value or deleted               Cannot be deleted or changed

参考文献

AS3基础知识:功能

我已经使用闭包做了如下的事情:

a = (function () {
    var privatefunction = function () {
        alert('hello');
    }

    return {
        publicfunction : function () {
            privatefunction();
        }
    }
})();

正如你在那里看到的,a现在是一个对象,它有一个方法publicfunction(a.publicfunction()),它调用privatefunction,它只存在于闭包中。你不能直接调用privatefunction(即a.b ratefunction()),只能调用publicfunction()。

这是一个最小的例子,但也许你可以看到它的用途?我们使用它来强制公共/私有方法。

闭包的使用:

闭包是JavaScript最强大的特性之一。JavaScript允许函数嵌套,并授予内部函数对外部函数中定义的所有变量和函数的完全访问权(以及外部函数可以访问的所有其他变量和函数)。但是,外部函数不能访问内部函数内部定义的变量和函数。

这为内部函数的变量提供了一种安全性。此外,由于内部函数可以访问外部函数的作用域,如果内部函数能够在外部函数的生命周期之后继续存在,那么外部函数中定义的变量和函数将比外部函数本身的生命周期更长。当内部函数以某种方式对外部函数之外的任何作用域可用时,就会创建闭包。

例子:

<script>
var createPet = function(name) {
  var sex;
  
  return {
    setName: function(newName) {
      name = newName;
    },
    
    getName: function() {
      return name;
    },
    
    getSex: function() {
      return sex;
    },
    
    setSex: function(newSex) {
      if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
        sex = newSex;
      }
    }
  }
}

var pet = createPet("Vivie");
console.log(pet.getName());                  // Vivie

console.log(pet.setName("Oliver"));   
console.log(pet.setSex("male"));
console.log(pet.getSex());                   // male
console.log(pet.getName());                  // Oliver
</script>

在上面的代码中,外部函数的name变量可以被内部函数访问,除了通过内部函数,没有其他方法访问内部变量。内部函数的内部变量充当内部函数的安全存储。它们保存“持久的”但安全的数据,供内部函数使用。这些函数甚至不需要赋值给变量,也不需要有名称。 详情请阅读此处。