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 相关文章推荐
JS 显示当前日期与时间的代码
Mar 24 Javascript
JQuery浮动DIV提示信息并自动隐藏的代码
Aug 29 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
Sep 17 Javascript
基于jquery的可多选的下拉列表框
Jul 20 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
Apr 18 Javascript
jQuery 无刷新分页实例代码
Nov 12 Javascript
详解Bootstrap按钮
Jan 04 Javascript
莱鸟介绍javascript onclick事件
Jan 06 Javascript
js 打开新页面在屏幕中间的实现方法
Nov 02 Javascript
基于JS实现翻书效果的页面切换样式
Feb 16 Javascript
Webpack 服务器端代码打包的示例代码
Sep 19 Javascript
JS+HTML5 canvas绘制验证码示例
Dec 05 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/11/06 PHP
PHP整合PayPal支付
2015/06/11 PHP
JavaScript 判断浏览器类型及版本
2009/02/21 Javascript
javascript div 遮罩层封锁整个页面
2009/07/10 Javascript
基于jquery tab切换(防止页面刷新)
2012/05/23 Javascript
基于JQuery的类似新浪微博展示信息效果的代码
2012/07/23 Javascript
浅析js封装和作用域
2013/07/09 Javascript
JavaScript函数获取事件源的小例子
2014/05/14 Javascript
JQuery中使文本框获得焦点的方法实例分析
2015/02/28 Javascript
JavaScript入门基础
2015/08/12 Javascript
js 判断所选时间(或者当前时间)是否在某一时间段的实现代码
2015/09/05 Javascript
原生js模拟淘宝购物车项目实战
2015/11/18 Javascript
Bootstrap选项卡与Masonry插件的完美结合
2016/07/06 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
2017/02/22 Javascript
ionic2打包android时gradle无法下载的解决方法
2017/04/05 Javascript
Angular.JS内置服务$http对数据库的增删改使用教程
2017/05/07 Javascript
详解javascript appendChild()的完整功能
2018/08/18 Javascript
Vue 中使用富文本编译器wangEditor3的方法
2019/09/26 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
2019/11/14 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
2020/11/17 Vue.js
如何在VUE中使用vue-awesome-swiper
2021/01/04 Vue.js
在Django中管理Users和Permissions以及Groups的方法
2015/07/23 Python
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
win10下python3.5.2和tensorflow安装环境搭建教程
2018/09/19 Python
python实现爬虫抓取小说功能示例【抓取金庸小说】
2019/08/09 Python
python批量处理文件或文件夹
2020/07/28 Python
浅谈Html5页面打开app的一些思考
2020/03/30 HTML / CSS
计算机应用专业学生的自我评价分享
2013/11/03 职场文书
工作建议书范文
2014/05/13 职场文书
婚礼秀策划方案
2014/05/19 职场文书
文秘自荐信
2014/06/28 职场文书
新娘父亲婚礼致辞
2015/07/27 职场文书
婚礼必备主持词范本!
2019/07/23 职场文书
Python数据分析之pandas函数详解
2021/04/21 Python
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis