• 闭包是什么?

初学javascript的人,都会接触到一个东西叫做闭包,听起来感觉很高大上的。网上也有各种五花八门的解释,其实我个人感觉,没必要用太理论化的观念来看待闭包。

事实上,你每天都在用闭包,只是你不知道罢了。

比如:

var cheese = '奶酪';var test = function(){alert(cheese);
}

OK,你已经写了一个闭包。

  • 函数也是一个数据类型

变量 cheese 是在全局作用域中的一个变量,当你创建了一个 test 函数,那么,test 和 cheese 就共享一个全局作用域。

你要额外明白的一点是,在js中,函数和变量本质上是一个东西。函数也是一个数据类型。

从上面的定义中也能看出来这一点。你要是不相信的话,我们来看一下咯。

alert(cheese);
alert(test);

让我们再来看看 test 和 cheese各是什么类型:

alert(typeof test);
alert(typeof cheese);

看到了吧,只是类型不同而已,他们都是数据类型。

唯一的不同点就是,函数类型的 test 可以拥有自己内部逻辑,而string类型的 cheese 只能存放一个字面值,这就是区别,仅此而已。

一目了然了,唯一不同的就是普通变量是字面值一样的存在,而函数需要打个括号才能执行而已。

你看,我现在打一个括号:

test();

打了括号,才会执行函数里面的逻辑。

  • 作用域

让我们回到闭包,现在将之前的代码做一个小小的变动:

var cheese = '奶酪';
var test = function(){alert(cheese);
}function test2(){var cheese = null;test();
}test2();

那么,你觉得现在 alert 出来的是 null 还是奶酪呢?

思考一下。。。

对的,弹出来的还是奶酪。

之前已经说过了,函数 test 和 变量 cheese 同处于一片蓝天下 -- 同一个作用域。

函数 test 和 变量 cheese 共同享有的作用域叫做全局作用域,就好像地球一样,我们所有的人都享有这个地球,能够在这里呼吸,吃饭,玩耍。

对test而言,他能访问到的作用域只有它本身的闭包和全局作用域:

Paste_Image.png

也就是说,正常情况下他访问不到其他闭包里的内容,在 test2 里面定义的变量跟它没有半毛钱关系,所以弹出来的 cheese 依旧是全局作用域里的 cheese。

函数可以创造自己的作用域。

我们刚才定义了一个 test 函数,{ } 包裹起来的部分就形成了一个新的作用域,也就是所谓的闭包。

其实你深刻了解了作用域的原理后,闭包也就理解了。

就好比地球是一个全局作用域,你自己家的房子是一个函数,你的房子是私人空间,就是一个局部作用域,也就是你自己建了一个闭包!

你透过窗户可以看见外边的景色,比如院子里的一棵芭蕉树,你于是通过眼镜观察看到了芭蕉树的颜色,高度,枝干的粗细等等。

这一棵芭蕉树相当于一个全局变量,你在自己的闭包内可以访问到它的数据。

所以,在这个例子中,test 就是一个房子,在里面可以通过窗户访问到全局作用域中的奶酪 —— 变量 cheese。

也就是说,cheese 在被 test 访问到的时候,就进入了它的闭包。

这样解释,你是否觉得好理解一点呢?

现在你是否可以理解一开始我说,闭包这东西其实我们天天都在用的意思了呢?

我们给出闭包的第一个注解:

1. 闭包就是在函数被创建的时候,存在的一个私有作用域,并且能够访问所有的父级作用域。

回到刚才的例子:

var cheese = '奶酪';
var test = function(){alert(cheese);
}function test2(){var cheese = null;test();
}

在这个例子中,test 和 test2 各自享有一个作用域,对不对?而且他们互相不能访问。比如,我在 test 中定义的一个变量,test2就无法直接访问。

var test = function(){var i = 10;
}function test2(){alert(i);
}test2();

像这样,一旦执行 test2 函数,编译就不通过,因为在 test2的闭包内,根本找不到变量 i 。它首先会在自己的闭包内寻找 i,找不到的话就去父级作用域里找,这边的父级就是全局作用域,很遗憾,还是没有。这就是所谓的作用域链,它会一级一级往上找。如果找到最顶层,还是找不到的话,就会报错了。

在这里,还有一个需要注意的点就是:如果某一个闭包中对全局作用域(或父级作用域)中的变量进行了修改,那么任何引用该变量的闭包都会受到牵连。

这的确是一个需要注意的地方。

举个例子

var cheese = '奶酪';var test = function(){cheese = '奶酪被偷吃了!'
}function test2(){alert(cheese);
}
test();
test2();

结果是:

Paste_Image.png

很有趣,是不是呢?

当我们在定义一个函数,就产生了一个闭包,如果这个函数里面又有若干的内部函数,就是闭包嵌套着闭包。

像这样:

function house(){var footBall = '足球';/* 客厅 */function livingRoom(){var table = '餐桌';var sofa = '沙发';alert(footBall);}/* 卧室 */function bedRoom(){var bed = '大床';}livingRoom();
}house(); 

函数house是一个闭包,里面又定义了两个函数,分别是livingRoom客厅,和bedRoom卧室,它们各自形成一个自己的闭包。对它们而言,父级作用域就是house。

如果我们希望在客厅里踢足球,在livingRoom函数执行的时候,它会先在自己的闭包中找足球,如果没找到,就去house里面找。一层一层往上找,直至找到了为止。当然,这个例子可能不是很恰当。但起码展示了作用域,闭包之间的联系。

再说明一下, 闭包就是在函数被创建的时候,存在的一个私有作用域,并且能够访问所有的父级作用域。因此,从理论上讲,任何函数都是一个闭包!

作者:剽悍一小兔
链接:https://www.jianshu.com/p/6f5833e261ac
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

转载于:https://www.cnblogs.com/dragonwave/p/9273580.html

(转)JavaScript: 零基础轻松学闭包(1)相关推荐

  1. 零基础轻松学python pdf 小码哥_零基础轻松学Python

    零基础轻松学Python电子书 Python之父Guido van Rossum力荐的Python门书.本书以通俗易懂的语言.好玩有趣的案例让读者轻轻松松.循序渐地从零始掌握Python 3 编程.本 ...

  2. python爬虫ppt_完全零基础 轻松学Python:数据类型:数字类型、空类型、布尔类型...

    Tip:点击上方或此处 "#完全零基础 轻松学Python" 话题,查看更多内容,欢迎点赞.分享.收藏,谢谢支持! 内 容 概 要 1. 数据类型概述 数据类型的概念.常见的八种数 ...

  3. 零基础学python全彩版pdf-(特价书)零基础轻松学Python:青少年趣味编程(全彩版)...

    基本信息 作者: 快学习教育 出版社:机械工业出版社 ISBN:9787111640004E上架时间:2020-5-26出版日期:2019 年11月开本:16开页码:176版次:1-1 所属分类: 科 ...

  4. 零基础学python全彩版-零基础轻松学Python:青少年趣味编程(全彩版)

    前言 如何获取学习资源 第1章 初识Python 001 孩子为什么要学编程11 002 为什么要学Python12 003 下载Python安装包12 004 安装Python14 005 配置编程 ...

  5. 零基础轻松学python青少年趣味编程pdf_零基础轻松学PYTHON:青少年趣味编程(全彩版) 快学习教育编著 著...

    前言 如何获取学习资源 第1章 初识Python 001 孩子为什么要学编程11 002 为什么要学Python12 003 下载Python安装包12 004 安装Python14 005 配置编程 ...

  6. 零基础轻松学mysql_零基础轻松学MySQL 5.7

    前 言 第1章 数据库概述 ·····································1 1.1 数据库基本概念 ·······························1 1. ...

  7. 手绘插画零基础怎么学?带你点线面轻松入门!

    手绘插画零基础怎么学?带你点线面轻松入门!自学插画,可以这样说,说有100个想零基础自学插画的人,有99个入门即劝退,倒在了基础练习上,枯燥.乏味.惰性.欲望等等都会让你没法坚持下去,但万丈高楼平地起 ...

  8. 零基础开始学前端有什么建议?

    如今,随着物联网时代的到来和网络营销的日益发展,前端技术比以往更加火热.我们可以看到Web应用与新技术趋势紧密相连,而这直接导致了前端行业广阔的就业前景.正因如此,学习前端的朋友越来越多了.为了帮助大 ...

  9. python零基础能学吗-终于知道深圳Python零基础能学吗

    近来一段时间总是有很多人在问深圳Python零基础能学吗到底有没有价值,大家对于深圳Python培训疑问的根源可能来自于多方面的,今天就通过Python能用来做什么,主要学习内容,文字云很难做吗,学P ...

最新文章

  1. [置顶] 如何搭建一个 Data Guard 环境
  2. php 数组去重_数组去重(JavaScript 为例)
  3. 交通违章行为,和记分、处罚条款——不仅要扣分,还要罚钱哪,没有不罚钱的扣分!!!...
  4. css3学习 之 css选择器(结构性伪类选择器)
  5. 用神经网络计算甲醛CH2O和亚硝酸HNO2的化学键的键能
  6. Btrace详细指南(JDK7,监控HashMap扩容)
  7. c++ builder xe2 (Embarcadero rad studio) 远程调试 同样适用于 delphi 远程调试 教程
  8. sql语句使用foreach报错
  9. linux操作系统之进程组及会话
  10. 可控硅失效现象_可控硅坏的原因有哪些
  11. ADC内设与外设的区别
  12. 美柚-产品原型图(高保真) 一个拥有腾讯产品梦的小精灵
  13. java中mouselistener的用法_关于MouseListener接口的简单使用
  14. 实习日志(1)2011-12-30
  15. 路由:vue-router
  16. ubuntu搭建无盘服务器,ubuntu配置无盘服务器
  17. 【BZOJ5285】【HNOI2018】寻宝游戏
  18. 饥荒联机版服务器控制台本地和在线,饥荒联机版控制台怎么打开_饥荒联机版控制台开启方法_牛游戏网...
  19. Web前端 笔记 (21-45)
  20. Java面试题(上)

热门文章

  1. Ubuntu21.04 deepin-wine 微信输入中文乱码,黑块,和多余窗口问题解决
  2. linux kill命令使用
  3. vue报错:Module build failed: Error: Node Sass does not yet support your current environment: Windows
  4. 【收藏】Sentinel 高可用流量管理框架、服务熔断降级等
  5. k8s部署nfs-client-provisioner完整实践版(亲测有效)
  6. 【网址收藏】k8s HPA自动伸缩异常:failed to get cpu utilization: missing request
  7. docker registry私有仓库搭建(为k3s准备)
  8. Java IO模型--BIO、NIO Single Thread、NIO Reactor、AIO单线程及多线程AIO
  9. Spring Boot 2.0.5 配置Druid数据库连接池
  10. spark写mysql优化简书_spark——通过jdbc连接数据库中遇到的问题