细说JS系列(十七)

99 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

铃铛说点题外话

一句话前情回顾:作用域分为全局作用域和局部作用域,查询变量会延着作用域链进行查找。

一句话介绍今天:接着说闭包闭包

今天就要把闭包打下来

铃铛说正文

image.png

上一篇举了个例子是将其中的函数return出去,但是是不是只有返回函数才能算是产生了闭包呢? 我们回到闭包的本质,我们只需要让父级作用域的引用存在即可,因此我们可以看下面的例子:

var f3;
function f1() {
  var a = 2
  f3 = function() {
    console.log(a);
  }
}
f1();
f3();

这段代码中,函数f1先被调用,函数f3被赋值,等于说现在函数f3拥有了函数f3自身、函数f1和全局window作用域的访问权限。还是先从自身作用域开始查找,最近是从函数f1中找到变量a,因此输出结果是2

在找个例子中是在外面调用函数f3存在着父级作用域的引用,因此也产生了闭包,虽然形式发生了改变,但是本质还是顺着作用域链查找,本质是没有变化的。

闭包有哪些表现形式

我们从本质出发,在真实场景中我们的闭包会在哪些场景中出现呢

  1. 返回一个函数(前篇的例子)
  2. 作为函数参数传递
var a = 1;
function foo(){
  var a = 2;
  function baz(){
    console.log(a);
  }
  bar(baz);
}
function bar(fn){
  // 这就是闭包
  fn();
}
// 输出2,而不是1
foo();

这里将函数baz作为参数,调用函数foo,里面将函数baz作为函数bar的参数,也就是调用函数bar,函数bar的作用域包括自身、函数foo和全局window作用域,这里首先在函数foo中找到变量a,输出2。

跟铃铛说再见

学习的最后一步:放松

今日冷笑话:小明理了头发,第二天来到学校,同学们看到他的新发型,笑道:小明,你的头型好像个风筝哦!小明觉得很委屈,就跑到外面哭。哭着哭着~他就飞起来了...

放松结束,猜猜明天会说讲些什么吧