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代码片段收集
Jul 12 Javascript
javascript dom追加内容实现示例
Sep 21 Javascript
jquery获取选中的文本和值的方法
Jul 08 Javascript
Javascript Memoizer浅析
Oct 16 Javascript
Javascript中Array.prototype.map()详解
Oct 22 Javascript
AngularJs页面筛选标签小功能
Aug 01 Javascript
真正好用的js验证上传文件大小的简单方法
Oct 27 Javascript
JavaScript之Date_动力节点Java学院整理
Jun 28 Javascript
原生JS控制多个滚动条同步跟随滚动效果
Dec 22 Javascript
vuejs+element UI点击编辑表格某一行时获取内容填入表单的示例
Oct 31 Javascript
JavaScript变量作用域及内存问题实例分析
Jun 10 Javascript
js实现类选择器和name属性选择器的示例步骤
Feb 07 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文件
2007/01/04 PHP
使用PHP实现密保卡功能实现代码<打包下载直接运行>
2011/10/09 PHP
php获取汉字首字母的函数
2013/11/07 PHP
PHP中strtr字符串替换用法详解
2014/11/26 PHP
Laravel5.5新特性之友好报错以及展示详解
2017/08/13 PHP
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
js选择并转移导航菜单示例代码
2014/08/19 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
移动开发之自适应手机屏幕宽度
2016/11/23 Javascript
详解Javascript中DOM的范围
2017/02/13 Javascript
详解webpack解惑:require的五种用法
2017/06/09 Javascript
JavaScript实现快速排序的方法分析
2018/01/10 Javascript
vue轮播图插件vue-concise-slider的使用
2018/03/13 Javascript
Vue实现的父组件向子组件传值功能示例
2019/01/19 Javascript
layui.use模块外部使用其内部定义的js封装函数方法
2019/09/16 Javascript
[01:57]2016完美“圣”典风云人物:国士无双专访
2016/12/04 DOTA
python中判断文件编码的chardet(实例讲解)
2017/12/21 Python
Python用imghdr模块识别图片格式实例解析
2018/01/11 Python
python实现LBP方法提取图像纹理特征实现分类的步骤
2019/07/11 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
Python 字典一个键对应多个值的方法
2020/09/29 Python
python em算法的实现
2020/10/03 Python
Python jieba结巴分词原理及用法解析
2020/11/05 Python
做一个能自适应高度的textarea的示例代码
2019/09/06 HTML / CSS
Pretty You London官网:英国拖鞋和睡衣品牌
2019/05/08 全球购物
自荐信模版
2013/10/24 职场文书
保安的辞职报告怎么写
2014/01/20 职场文书
关于爱国的演讲稿
2014/05/07 职场文书
教育合作协议范本
2014/10/17 职场文书
2014年领导班子工作总结
2014/12/11 职场文书
小学班主任事迹材料
2014/12/17 职场文书
通知格式
2015/04/27 职场文书
培训心得体会怎么写
2016/01/25 职场文书
PostgreSQL基于pgrouting的路径规划处理方法
2022/04/18 PostgreSQL