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 相关文章推荐
jQuery 1.0.2
Oct 11 Javascript
JavaScript中的toLocaleDateString()方法使用简介
Jun 12 Javascript
利用jQuery设计一个简单的web音乐播放器的实例分享
Mar 08 Javascript
JavaScript驾驭网页-获取网页元素
Mar 24 Javascript
JS获取checkbox的个数简单实例
Aug 19 Javascript
JS控制TreeView的结点选择
Nov 11 Javascript
jQuery实现模拟flash头像裁切上传功能示例
Dec 11 Javascript
Javascript下拉刷新的简单实现
Feb 14 Javascript
JS轮播图实现简单代码
Feb 19 Javascript
layer 关闭指定弹出层的例子
Sep 25 Javascript
详解vue组件之间的通信
Aug 30 Javascript
vue cli 3.0通用打包配置代码,不分一二级目录
Sep 02 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随机输出名人名言的代码
2012/10/07 PHP
PHP中PDO事务处理操作示例
2018/05/02 PHP
在页面上点击任一链接时触发一个事件的代码
2007/04/07 Javascript
javascript省市级联功能实现方法实例详解
2015/10/20 Javascript
基于javascript实现的快速排序
2016/12/02 Javascript
详解jQuery lazyload 懒加载
2016/12/19 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
2017/02/10 Javascript
JS 实现banner图片轮播效果(鼠标事件)
2017/08/04 Javascript
JavaScript实现计数器基础方法
2017/10/10 Javascript
解决百度Echarts图表坐标轴越界的方法
2018/10/17 Javascript
11个教程中不常被提及的JavaScript小技巧(推荐)
2019/04/17 Javascript
微信小程序 如何获取网络状态
2019/07/26 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
2019/09/11 Javascript
如何在Vue中使localStorage具有响应式(思想实验)
2020/07/14 Javascript
[02:26]DOTA2英雄米拉娜基础教程
2013/11/25 DOTA
[02:03]永远的信仰DOTA2 中国军团历届国际邀请赛回顾
2016/06/26 DOTA
python下读取公私钥做加解密实例详解
2017/03/29 Python
Python加载带有注释的Json文件实例
2018/05/23 Python
Flask-Mail用法实例分析
2018/07/21 Python
Python增强赋值和共享引用注意事项小结
2019/05/28 Python
sklearn线性逻辑回归和非线性逻辑回归的实现
2020/06/09 Python
keras的siamese(孪生网络)实现案例
2020/06/12 Python
Python实现验证码识别
2020/06/15 Python
python导入库的具体方法
2020/06/18 Python
CSS3的first-child选择器实战攻略
2016/04/28 HTML / CSS
新西兰演唱会和体育门票网站:Ticketmaster新西兰
2017/10/07 全球购物
Joules美国官网:出色的英国风格
2017/10/30 全球购物
Bata印度官网:源自欧洲舒适鞋履品牌
2020/01/30 全球购物
教师自荐书
2013/10/08 职场文书
客服主管岗位职责
2013/12/13 职场文书
暑期实践思想汇报
2014/01/06 职场文书
高校教师自荐信范文
2014/03/13 职场文书
党的群众路线教育实践活动个人对照检查剖析材料
2014/09/23 职场文书
通知书大全
2015/04/27 职场文书
学法用法心得体会(2016推荐篇)
2016/01/21 职场文书
go开发alertmanger实现钉钉报警
2021/07/16 Golang