关于闭包

  闭包,一个老生常谈的前端问题,同时也是一个面试大概率会问到的问题。这里我综合自己在网上看到的和自己所理解的做一点小小的总结

什么是闭包

  闭包能够读取其他函数内部变量的函数。只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

  相较于其他地方的解释,百度百科的这个翻译更能让人理解、更通俗易懂。首先,闭包是函数,什么样的函数,定义在函数内部的函数。那他是怎么成为函数内部和外部连接的桥梁的呢?

  首先我们来看一下这个例子:

 1 function returnFoo() {
 2     let name = "fire&forget";    //定义一个函数内部变量
 3     function displayName() {    //定义一个函数内部子函数
 4         alert(name);
 5     }
 6     return displayName;    //返回子函数
 7 }
 8 
 9 var foo = returnFoo();    //将返回的子函数赋值给foo
10 foo();    //alert("fire&forget")

  在这个例子中,我们执行方法foo()时,会出现弹框并打印出name的值。但是returnFoo函数中的值,我们无法直接访问到。 在这里,displayName()方法就是我们生成的一个闭包。而在调用foo()时,我们实则调用的就是displayName()从而打印出了returnFoo函数中的name变量。因此,他实现了returnFoo函数内外部连接的作用。

  看到这里,做过OOP的同学是不是觉得很熟悉? 

  我们再来看下一个例子:

 1 let Person = function (name1, age1, sex1) {
 2     let name = name1;
 3     let age = age1;
 4     let sex = sex1;
 5     return {
 6         getName: function () {
 7             return name;
 8         },
 9         setName: function (name1) {
10               name = name1;
11            },
12         getAge: function () {
13               return age;
14         },
15         setAge: function (age1) {
16             age = age1;
17         },
18         getSex: function () {
19             return sex;
20         },
21         setSex: function (sex1) {
22             sex = sex1;
23         },
24         toString: function () {
25             console.log("name:" + name + ";age:" + age + ";sex:" + sex);
26         }
27     }
28 }
29 let user1 = Person("peter","23","male");
30 user1.getAge();    //23
31 user1.setAge(18);
32 user1.getAge();    //18
33 user1.toString();    //name:perter;age:18;sex:male

  这样一看,这个Person()函数不就是一个活生生的对象嘛!这个对象内涵了3个私有变量name、age、sex。不能直接访问,必须通过调用get方法访问;不能直接修改,必须通过调用set方法修改。

  所以闭包最大的应用场景就是创建对象模拟私有变量/方法。

——————————————————————————————————————  

  至于MDN中还指出了可以用于回调,但我个人觉得不太实用。首先写出来后代码比较复杂,且解读性不强,不利于后期维护。(当然,这都是自己的一点拙见,如有错误请大家及时指出!谢谢阅读!)

  

posted @ 2019-11-12 16:59  Wolfeather  阅读(155)  评论(0编辑  收藏  举报