JavaScript闭包相关知识解析


Posted in Javascript onOctober 19, 2019

闭包是JavaScript中的一个难点,同时也是它的特色,JavaScript的很多高级应用都要依靠闭包来实现。以下是我学习闭包的记录,希望对你有些帮助。

变量作用域

在学习闭包之前,我们首先要理解JavaScript不同与其他语言独特的变量作用域。在JavaScript中,不存在局部作用域的概念,但是有全局作用域以及函数作用域。全局作用域与其他语言的相同,没有需要注意的地方,而函数作用域是指函数内部声明的变量在函数外部无法直接访问。

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

上面的代码中,f1可以读取到全局变量a,而下面的代码中a无法被访问。

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

如何从外部读取函数内部声明的变量?

在某些情况下,我们可能需要得到函数内部的变量,正常情况下是无法做到的,因此需要用特殊的办法。

function f1() {
  var a = 99;
  function f2() {
    console.log(a);
  }
}

上面代码中,我们在函数f1中定义另一个函数f2,这样f1中的所有变量对于f2来说就是可见的,既然f2可以读取到f1中的变量,那么我们只要把f2作为f1的返回值,我们就可以在f1的外部读取到它内部的变量了。

function f1() {
  var a = 99;
  function f2() {
    console.log(a);
  }
  return f2;
}
var result = f1();
result();

此时,就形成了一个简单的闭包。因此,闭包就可以简单的理解为函数中的函数,而本质上,闭包就是一个连接函数内部和外部的桥梁。

闭包的特性

闭包会使得函数中的变量都被保存到内存中。首先我们先看一下以下两个例子

function A() {
  var count = 0;
  function B() {
    count++;
    console.log(count);
  }
  return B;
}
var C = A();
C(); // 1
C(); // 2
C(); // 3

count是函数A中的一个变量,它的值在函数B中被改变,函数B每执行一次,count的值就在原来的基础上累加1,因此,函数A中的count变量会一直保存在内存中。

function A(x) {
  function B(y) {
    console.log(x+y);
  }
return B;
}
var C = A(3);
C(5); //8

当3传入A函数后,B函数就会记住这个值,所以在后面传入5的时候只会对B函数中的y赋值,所以最后会输出8。

使用闭包的注意点

由于上述闭包的特性,每次使用闭包都会大量增加内存的消耗,所以不能滥用闭包,否则会影响网页的性能。我们也可以在函数退出前,使函数内变量指向null来手动删除变量。我们可以来看下一道经典的面试题来理解。

function outer(){
  var num = 0; //内部变量
  return function add() { //通过return返回add函数,就可以在outer函数外访问了
    num++; //内部函数有引用,作为add函数的一部分了
    console.log(num);
  };
}
var func1 = outer();
func1(); //实际上是调用add函数, 输出1
func1(); //输出2 因为outer函数内部的私有作用域会一直被占用
var func2 = outer();
func2(); // 输出1 每次重新引用函数的时候,闭包是全新的。
func2(); // 输出2

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jsTree的无限级树JSON数据的转换代码
Jul 27 Javascript
基于jquery中children()与find()的区别介绍
Apr 26 Javascript
jquery右下角弹出提示框示例代码
Oct 08 Javascript
通过Javascript读取本地Excel文件内容的代码示例
Apr 08 Javascript
js实现遮罩层划出效果是生成div而不是显示
Jul 29 Javascript
限制上传文件大小和格式的jQuery插件实例
Jan 24 Javascript
使用js获取地址栏参数的方法推荐(超级简单)
Jun 14 Javascript
javascript判断firebug是否开启的方法
Nov 23 Javascript
for循环 + setTimeout 结合一些示例(前端面试题)
Aug 30 Javascript
postman+json+springmvc测试批量添加实例
Mar 31 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
Jul 17 Javascript
vue+koa2搭建mock数据环境的详细教程
May 18 Javascript
Vue.js组件通信之自定义事件详解
Oct 19 #Javascript
Vue.js自定义指令学习使用详解
Oct 19 #Javascript
Vue.js标签页组件使用方法详解
Oct 19 #Javascript
基于JavaScript获取base64图片大小
Oct 18 #Javascript
react MPA 多页配置详解
Oct 18 #Javascript
vue滚动插件better-scroll使用详解
Oct 18 #Javascript
VUE实现密码验证与提示功能
Oct 18 #Javascript
You might like
PHP创建/删除/复制文件夹、文件
2016/05/03 PHP
bcastr2.0 通用的图片浏览器
2006/11/22 Javascript
用JavaScript调用WebService的示例
2008/04/07 Javascript
javascript 基础篇2 数据类型,语句,函数
2012/03/14 Javascript
JQuery表格内容过滤的实现方法
2013/07/05 Javascript
原始XMLHttpRequest方法详情回顾
2013/11/28 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
JS对字符串编码的几种方式使用指南
2015/05/14 Javascript
jQuery实现返回顶部功能
2016/02/23 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
详解nodejs微信公众号开发——2.自动回复
2017/04/10 NodeJs
zTree异步加载展开第一级节点的实现方法
2017/09/05 Javascript
webpack3之loader全解析
2017/10/26 Javascript
Jquery实现无缝向上循环滚动列表的特效
2019/02/13 jQuery
使用react context 实现vue插槽slot功能
2019/07/18 Javascript
在vue中根据光标的显示与消失实现下拉列表
2019/09/29 Javascript
Vue.js组件props数据验证实现详解
2019/10/19 Javascript
JS简易计算器实例讲解
2020/06/30 Javascript
初步理解Python进程的信号通讯
2015/04/09 Python
用Python编写web API的教程
2015/04/30 Python
解读Python中degrees()方法的使用
2015/05/18 Python
python 排序算法总结及实例详解
2016/09/28 Python
python接入支付宝的实例操作
2020/07/20 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
html5 学习简单的拾色器
2010/09/03 HTML / CSS
使用HTML5进行SVG矢量图形绘制的入门教程
2016/02/19 HTML / CSS
Html5移动端div固定到底部实现底部导航条的几种方式
2021/03/09 HTML / CSS
吉列剃须刀美国官网:Gillette美国
2018/07/13 全球购物
毕业生实习证明
2014/09/19 职场文书
美国旅游签证工作证明
2014/10/14 职场文书
社区文明创建工作总结2015
2015/04/21 职场文书
2015年班干部工作总结
2015/04/29 职场文书
大卫科波菲尔读书笔记
2015/06/30 职场文书
创业分两种人:那么哪些适合创业?,哪些适合不适合创业呢?
2019/08/23 职场文书
教你用Python matplotlib库制作简单的动画
2021/06/11 Python
搭建Yolov5服务器
2022/04/30 Servers