闭包认知
闭包认知
7月 6, 2020
·
3 分钟阅读时长
·
1036
字
·
-阅读
-评论
最近在梳理JS基础,觉得
闭包这个知识点并不清晰,研究了会儿,所谓踏雪有痕,这里MARK下。
什么是闭包
函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成 闭 包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。
摘自MDN
注意
- 函数作用域,不是块作用域
 - 闭包是有状态的函数
 
先上几个例子,看看谁是闭包
例子1
   function init() {
        var name = 'Mozilla'; // name 是一个被 init 创建的局部变量
        function displayName() {
          // displayName() 是内部函数
          alert(name); // 使用了父函数中声明的变量
        }
        displayName();
      }
      init();

例子2
function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}
var myFunc = makeFunc();
myFunc();

TIP
注意,Chrome调试状态下是可以看出来谁是闭包的。有助于去理解。
通过这几个例子实际上可以这么去说
闭包即是可以访问其他函数作用域内变量的函数对象,同时你可以说闭包是有状态的函数。
闭包的运用
知道谁是闭包,那么就是闭包可以干嘛。
- 封装私有变量
 - 模块
 - 用在块作用域上
 - 监听器
 
这几种用法,我们只是有意无意的在使用,可能只是不知道而已。
闭包是一种技术,不限语言
如上,闭包Closure是一种技术手段,所以与语言无关,那么比如java有闭包吗。有的。
Java中的闭包
比如最常见的lambda中,我们传入传入外部函数变量,从而形成闭包。
int factor = 3;
numbers.stream()
  .filter(e -> e % 2 == 0)
  .map(e -> e * factor)
  .collect(toList());
为什么说这是个闭包,注意factor是函数外部的函数词法坏境
概念困惑 - lambda,匿名函数,闭包
- lambda即匿名函数,两个叫法而已
 - 闭包跟匿名函数并不同,如上例子中,如果factor去掉,其实就不是闭包了
 
上题
闭包后,来看几道复杂点的题。
题1
function fun(n, o) { 
  console.log(o);
  return { 
    fun: function(m) { // ③
           debugger;
      return fun(m, n); // ④ 
    }
  };
}
// 第一个例子
var a = fun(0); // 返回undefined
a.fun(1); // 返回 0
a.fun(2); // 返回 0
a.fun(3); // 返回 0
// 第二个例子
var b = fun(0)
  .fun(1)
  .fun(2)
  .fun(3); // undefined,0,1,2
// 第三个例子
var c = fun(0).fun(1);
c.fun(2);
c.fun(3); // undefined,0,1,1

题2
   var myObject = {
        foo: 'bar',
        func: function () {
          var self = this;
          console.log('outer func:  this.foo = ' + this.foo);  // bar
          console.log('outer func:  self.foo = ' + self.foo);   // bar
          (function () {
            console.log('inner func:  this.foo = ' + this.foo); // unfefined
            console.log('inner func:  self.foo = ' + self.foo); // bar
          })();
        },
      };
      myObject.func();

- 这道题理论上多个考察点就是
this指向问题,记得以前看书时,有句话讲的很棒,this永远指向调用它的对象。比如这里就是myObject。 - func及其
 
写在最后
编程界崇尚以简洁优雅为美,很多时候如果你觉得一个概念很复杂,那么很可能是你理解错了,这句话深表认同。带着这样的认识去看待诸如闭包这样的概念,我想应该会更简单些。

