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实现读取txt文档的脚本
Jul 20 Javascript
javascript面向对象之二 命名空间
Feb 08 Javascript
JavaScript模板入门介绍
Sep 26 Javascript
用正则表达式替换图片地址img标签
Nov 22 Javascript
jQuery事件绑定与解除绑定实现方法
Apr 15 Javascript
jQuery实现简单的图片查看器
Sep 11 Javascript
jQuery Dialog 取消右上角删除按钮事件
Sep 07 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
Feb 11 Javascript
微信小程序在地图选择地址并返回经纬度简单示例
Dec 03 Javascript
JavaScript的变量声明与声明提前用法实例分析
Nov 26 Javascript
js中的面向对象之对象常见创建方法详解
Dec 16 Javascript
Element-ui Layout布局(Row和Col组件)的实现
Dec 06 Vue.js
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获取网卡地址的代码
2008/04/09 PHP
PHP读取文件并可支持远程文件的代码分享
2012/10/03 PHP
smarty实现多级分类的方法
2014/12/05 PHP
js 中{},[]中括号,大括号使用详解
2011/05/12 Javascript
jquery一般方法介绍 入门参考
2011/06/21 Javascript
javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图
2013/01/09 Javascript
JavaScript中window、doucment、body的解释
2013/08/14 Javascript
escape函数解决js中ajax传递中文出现乱码问题
2014/10/30 Javascript
js制作简易年历完整实例
2015/01/28 Javascript
Juery解决tablesorter中文排序和字符范围的方法
2015/05/06 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
Bootstrap中data-target 到底是什么
2017/02/14 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
2018/05/16 jQuery
小程序开发基础之view视图容器
2018/08/21 Javascript
细说webpack6 Babel的使用详解
2019/09/26 Javascript
three.js着色器材质的内置变量示例详解
2020/08/16 Javascript
利用 JavaScript 实现并发控制的示例代码
2020/12/31 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
[03:46]DAC趣味视频-中文考试.mp4
2017/04/02 DOTA
分析python服务器拒绝服务攻击代码
2014/01/16 Python
Python-OpenCV基本操作方法详解
2018/04/02 Python
Python编程深度学习计算库之numpy
2018/12/28 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
2019/09/20 Python
Python输出指定字符串的方法
2020/02/06 Python
Python标准库:内置函数max(iterable, *[, key, default])说明
2020/04/25 Python
在Sublime Editor中配置Python环境的详细教程
2020/05/03 Python
CSS教程:CSS3圆角属性
2009/04/02 HTML / CSS
css3弹性盒模型(Flexbox)详细介绍
2014/10/08 HTML / CSS
台湾东南旅游社网站:东南旅游
2019/02/11 全球购物
美国儿童服装、家具和玩具精品店:Maisonette
2019/11/24 全球购物
Solaris操作系统的线程机制
2012/12/23 面试题
年会活动策划方案
2014/01/23 职场文书
高中历史教学反思
2014/02/08 职场文书
实习证明格式范文
2015/06/16 职场文书
Go gRPC进阶教程gRPC转换HTTP
2022/06/16 Golang