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 相关文章推荐
两种常用的javascript数组去重方法思路及代码
Mar 26 Javascript
js、jquery图片动画、动态切换示例代码
Jun 03 Javascript
javascript模拟php函数in_array
Apr 27 Javascript
ArtEditor富文本编辑器增加表单提交功能
Apr 18 Javascript
以WordPress为例讲解jQuery美化页面Title的方法
May 23 Javascript
PHP+jquery+ajax实现分页
Dec 09 Javascript
ES6生成器用法实例分析
Apr 10 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
Jun 09 jQuery
Vue项目webpack打包部署到服务器的实例详解
Jul 17 Javascript
对Vue beforeRouteEnter 的next执行时机详解
Aug 25 Javascript
React 实现拖拽功能的示例代码
Jan 06 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
Sep 26 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错误提示及查错方法
2015/07/14 PHP
thinkPHP实现签到功能的方法
2017/03/15 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
Javascript this指针
2009/07/30 Javascript
javascript Firefox与IE 替换节点的方法
2010/02/24 Javascript
javascript 文件的同步加载与异步加载实现原理
2012/12/13 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
2015/03/13 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
Bootstrap使用基础教程详解
2016/09/05 Javascript
Web前端开发之水印、图片验证码
2016/11/27 Javascript
微信小程序 图片宽度自适应的实现
2017/04/06 Javascript
JavaScript中字符串的常用操作方法及特殊字符
2018/03/18 Javascript
基于node搭建服务器,写接口,调接口,跨域的实例
2018/05/13 Javascript
微信小程序之批量上传并压缩图片的实例代码
2018/07/05 Javascript
JS函数节流和防抖之间的区分和实现详解
2019/01/11 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
JS替换字符串中指定位置的字符(多种方法)
2020/05/28 Javascript
[06:42]DOTA2每周TOP10 精彩击杀集锦vol.1
2014/06/25 DOTA
从Python的源码浅要剖析Python的内存管理
2015/04/16 Python
python计算时间差的方法
2015/05/20 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
2018/04/23 Python
Python实现快速傅里叶变换的方法(FFT)
2018/07/21 Python
python获取地震信息 微信实时推送
2019/06/18 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
python实现名片管理器的示例代码
2019/12/17 Python
django美化后台django-suit的安装配置操作
2020/07/12 Python
Kathmandu新西兰官网:新西兰户外运动品牌
2019/07/27 全球购物
销售高级职员求职信
2013/10/29 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
入党积极分子评语
2014/05/04 职场文书
村班子对照检查材料
2014/08/18 职场文书
2014年超市工作总结
2014/11/19 职场文书
2015年保险公司内勤工作总结
2015/05/23 职场文书
幼儿园保教工作总结2015
2015/10/15 职场文书
MySql存储过程之逻辑判断和条件控制
2021/05/26 MySQL
Python爬虫实战之爬取京东商品数据并实实现数据可视化
2021/06/07 Python