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渐显(fadeIn)渐隐(fadeOut)类
Jun 19 Javascript
入门基础学习 ExtJS笔记(一)
Nov 11 Javascript
javascript管中窥豹 形参与实参浅析
Dec 17 Javascript
DOM和XMLHttpRequest对象的属性和方法整理
Jan 04 Javascript
node.js Web应用框架Express入门指南
May 28 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
Aug 15 Javascript
jfinal与bootstrap的登录跳转实战演习
Sep 22 Javascript
浅谈几种常用的JS类定义方法
Jun 08 Javascript
AngularJS常见过滤器用法实例总结
Jul 06 Javascript
vue如何根据网站路由判断页面主题色详解
Nov 02 Javascript
js实现按钮开关单机下拉菜单效果
Nov 22 Javascript
微信公众平台 客服接口发消息的实现代码(Java接口开发)
Apr 17 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
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
解析php中如何直接执行SHELL
2013/06/28 PHP
在JavaScript中监听IME键盘输入事件
2011/05/29 Javascript
合并table相同单元格的jquery插件分享(很精简)
2011/06/20 Javascript
javascript实现图片切换的幻灯片效果源代码
2012/12/12 Javascript
JavaScript设计模式之外观模式介绍
2014/12/28 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
2015/04/25 Javascript
理解Javascript图片预加载
2016/02/23 Javascript
js给table赋值的实例代码
2016/10/13 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
2017/07/31 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
vue2.0 实现页面导航提示引导的方法
2018/03/13 Javascript
JS中的算法与数据结构之队列(Queue)实例详解
2019/08/20 Javascript
JavaScript设计模式---单例模式详解【四种基本形式】
2020/05/16 Javascript
从零开始用webpack构建一个vue3.0项目工程的实现
2020/09/24 Javascript
[01:32]寻找你心中的那团火 DOTA2 TI9火焰传递活动今日开启
2019/05/16 DOTA
Pyramid将models.py文件的内容分布到多个文件的方法
2013/11/27 Python
Python实现二叉堆
2016/02/03 Python
windows系统下Python环境搭建教程
2017/03/28 Python
Python利用matplotlib生成图片背景及图例透明的效果
2017/04/27 Python
python flask中静态文件的管理方法
2018/03/20 Python
Django ManyToManyField 跨越中间表查询的方法
2018/12/18 Python
python 叠加等边三角形的绘制的实现
2019/08/14 Python
简单了解python字符串前面加r,u的含义
2019/12/26 Python
Python多分支if语句的使用
2020/09/03 Python
Urban Outfitters德国官网:美国跨国生活方式零售公司
2018/05/21 全球购物
英国异国风情旅游网站:Travel Talk Tours(团体旅游、探险旅游、帆船假期)
2018/07/26 全球购物
印度民族服装购物网站:BIBA
2019/08/05 全球购物
组织关系转移介绍信
2014/01/16 职场文书
后勤服务中心总经理工作职责
2014/03/03 职场文书
诚信的演讲稿范文
2014/05/12 职场文书
酒店管理毕业生自荐信
2014/05/25 职场文书
最美孝心少年事迹材料
2014/08/15 职场文书
运动会广播稿150字(9篇)
2014/09/20 职场文书
观看建国大业观后感
2015/06/01 职场文书
详解Python描述符的工作原理
2021/06/11 Python