1.前言

闭包这个东西在JavaScript中是一个很强大的东西,但是在初学的阶段总是被其概念绕晕,搞不清楚到底什么是闭包,感觉很高深。作者在刚学的时候也有一点懵圈,多看几次就会有自己的理解。任何东西都没有唯一的标准,只要适合自己,自己能够理解的就是正确的。由于作者水平有限,将自己的一些见解拿出来,希望大家能够提出宝贵的意见。

2.作用域

在正式讲闭包之前,我们来简单的说一说作用域这个东西。这个很有助于大家理解后面的闭包。
什么是域?简单的说就是一个被圈起来的地方,也就是变量能够访问的一个范围。
众所周知,变量的作用域分为全局变量和局部变量。定义在函数外部的称为全局变量,在函数内部的称为局部变量。这里顺带提一下,变量提升这个玩意儿,也就是和“先声明后使用差不多的道理”,后面我将会举一个例子来说明。
举个例子,全局变量和局部变量:

1
2
3
4
5
6
7
8
9
10
11
12
复制代码
var a='wang';
function fun(){var b='huagang';console.log('这是在函数内部的输出');console.log(a);console.log(b);
}
fun();//调用函数console.log("这是在函数外部的输出");
console.log(a);
console.log(b);
复制代码

运行结果:

最后一个输出b的时候抛出了一个未定义异常,由此可见,全局变量(a)在函数内部和外部都是能访问的,但是局部变量不是这样的,在函数作用域外是不能访问到函数内部的变量(b)的。这里顺带讲一下【变量提升】吧,简单的举一个例子。

1
2
3
4
复制代码
var a;
console.log(a);
a='wang';
console.log(a)
复制代码

根据输出情况可以看出,第一次输出a并没有报异常,而是undefined。第二次便能输出a的值。这就是变量提升的特点,在变量还没赋值前就拿来使用了。

3.嵌套函数的作用域

嵌套函数,顾名思义就是在函数的内部再写一个或多个函数。下面举一个例子来讲解一下嵌套函数的作用域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
复制代码
function funA(c){var a='wang';function funB(){var b='gang';console.log("在函数B中的输出:")console.log(a);console.log(c);console.log(b);}funB();console.log("在函数A中的输出:")console.log(a);console.log(c);console.log(b);
}
funA('hua');//调用函数A并传参
复制代码

函数B就是嵌套在函数A中的嵌套函数,它可以继承函数A的变量和参数,但是B中的变量A是不能访问的,就好像B给自己的门上了锁,“只进不出”,我可以拿你的东西,但是你不可以拿我的东西。B这样就形成了一个自己独有的封闭空间,这就是一个闭包。
从不同的角度来看:从语法结构上看,函数A包含函数B;从作用域来看,函数B包含函数A,也就是说B能访问的空间比A大。
因此可以想象得出,假如B函数中还有一个嵌套函数X,那么这个X函数也是一个闭包,作用域包含B和A。这样下去就形成了一个作用域链。

4.闭包

相信通过上面的讲解,大家已经懂得了什么是闭包,现在再讲讲一些关于闭包的特点或者特性吧。

保存变量

什么是保存变量?加入B这个闭包需要两个变量才能运行,但是刚开始只传了一个参数进去,所以这时候闭包就会把这个变量的值进行保存,等待第二个变量传入,而不是丢弃这个变量的值。下面举一个例子进行说明吧。

1
2
3
4
5
6
7
8
9
复制代码
function funA(a){function funB(b){return a + b;}return funB;//调用函数B的引用
}
var x = funA(2);
var sum = x(3);
console.log(sum);//输出结果 5
复制代码

当函数A传进参数a=2时,这时闭包B就将a进行保存,等到再传b=3时再进行计算。这就是闭包的保存变量。

5.为什么要使用闭包

使用闭包的最大的好处——避免变量的污染。也就是说你在闭包中声明的变量不会影响在其他地方也使用这个变量名称,因为闭包将这个变量锁在自己的门里面保护起来了,外部是无法修改的。

1
2
3
4
5
6
7
8
9
10
11
复制代码
function funA(){function funB(b){var a = 'wang';//内部变量 creturn a+b ;}return funB;
}
var a = 'hua';//外部变量x,是不能改变闭包B中的变量a的
var sum = funA()(a);
console.log(a);
console.log(sum);
复制代码

可以看出,外部变量是不能修改闭包中的变量a的值的,从而保护了a的值,使其不会受到污染。

闭包的分享就讲到这里啦,我相信大家能够对闭包能够有一定的了解。当然,由于作者水平有限,这只是个人的见解,有误的地方还希望多多包涵,或者留言告知我。

我的博客地址:【咕噜先森的博客】

个人微信公众号:【咕噜有得聊】,欢迎关注,一起学习!

闭包 | 浅谈JavaScript闭包问题相关推荐

  1. 浅谈javascript中原型(prototype)、构造函数、对象实例及三者之间的关系

    转自:http://www.cnblogs.com/zhangwei412827/archive/2012/12/14/2816263.html 浅谈javascript中原型(prototype). ...

  2. 浅谈JavaScript作用域,关于Java的学习路线资料

    javascript是目前web领域中使用非常广泛的语言,不管是在前端还是在后端都能看到它的影子,可以说web从业者不论怎样都绕不开它.在前端领域,各种框架层出不穷.在后端领域,nodejs可谓如火如 ...

  3. 浅谈 JavaScript 编程语言的编码规范--转载

    原文:http://www.ibm.com/developerworks/cn/web/1008_wangdd_jscodingrule/ 对于熟悉 C/C++ 或 Java 语言的工程师来说,Jav ...

  4. JavaScript 中的 require / exports、import / export、浅谈JavaScript、ES5、ES6

    Node.js 的基础教学 之 exports 和 module.exports:https://zhuanlan.zhihu.com/p/82057593 浅谈 JavaScript.ES5.ES6 ...

  5. html 滚动条 scrolltop scrollheight,浅谈JavaScript中scrollTop、scrollHeight、offsetTop、offsetHeight...

    浅谈JavaScript中scrollTop.scrollHeight.offsetTop.offsetHeight 发布时间:2020-07-17 09:27:20 来源:亿速云 阅读:223 作者 ...

  6. 浅谈 JavaScript 编程语言的编码规范

    转自:http://www.ibm.com/developerworks/cn/web/1008_wangdd_jscodingrule/?ca=drs-tp4608 developerWorks 中 ...

  7. 浅谈JavaScript中的NaN

    浅谈JavaScript中的NaN NaN概念以及简单案例 追寻的纯粹该拥有自己的本质.-JC.F 什么是NaN? NaN:NaN(Not a Number),它表示不是数字,但是仍是数值类型. Na ...

  8. 浅谈JavaScript中闭包

    引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...

  9. python封装继承多态_浅谈JavaScript的面向对象和它的封装、继承、多态

    写在前面 既然是浅谈,就不会从原理上深度分析,只是帮助我们更好地理解... 面向对象与面向过程 面向对象和面向过程是两种不同的编程思想,刚开始接触编程的时候,我们大都是从面向过程起步的,毕竟像我一样, ...

最新文章

  1. 【2017-4-26】Winform 公共控件 菜单和工具栏
  2. pandas自定义设置dataframe每个索引的标签、自定义设置索引的列名称(customize index name and index label)
  3. 如何理解最小二乘法(19世纪的统计学就相当于18世纪的微积分对于数学的地位)
  4. Spring Ioc注解式开发中注解的作用
  5. samba服务器有什么安全风险_自体脂肪填充面部安全吗?有什么风险?
  6. Editability on SAP Text
  7. P2P网络穿越 NAT穿越
  8. php 获取localstorage,浅谈localStorage的本地存储
  9. 如何查询oracle的共享内存,[20190104]ipcs查看共享内存段.txt
  10. Oracle中exp的使用2
  11. PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.23. 行和数组比较
  12. [转]用C#编写ActiveX控件
  13. UESTC_神秘绑架案 CDOJ 881
  14. ASP.NET MVC搭建项目后台UI框架—9、服务器端排序
  15. 为什么企业要做CMMI资质认证?
  16. 蒙特卡洛与遗传算法介绍
  17. Android应用系列:手把手教你做一个小米通讯录(附图附源码)
  18. 《Java I/O》Chapter 1
  19. 读 活着 【思维导图版】
  20. Java中string字符串和char字符之间的千丝万缕

热门文章

  1. 汇编语言子程序的汇编及与C程序的连接
  2. 如果有一个类是 myClass , 关于下面代码正确描述的是?
  3. 常考数据结构与算法:反转链表
  4. 《编码:隐匿在计算机软硬件背后的语言(美)》读书笔记六
  5. python五:运算符
  6. 后台技术-JavaWeb项目初识
  7. Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)
  8. .NET程序在Linux容器中的演变
  9. CentOS6.5环境使用keepalived实现nginx服务的高可用性及配置详解
  10. 19、Cocos2dx 3.0游戏开发找小三之Action:流动的水没有形状,漂流的风找不到踪迹、、、...