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实时获取系统当前时间实例代码
Jun 28 Javascript
jQuery-ui引入后Vs2008的无智能提示问题解决方法
Feb 10 Javascript
JavaScript点击按钮后弹出透明浮动层的方法
May 11 Javascript
javascript元素动态创建实现方法
May 13 Javascript
D3.js实现折线图的方法详解
Sep 21 Javascript
JS前端笔试题分析
Dec 19 Javascript
解决VUEX刷新的时候出现数据消失
Jul 03 Javascript
express+mockjs实现模拟后台数据发送功能
Jan 07 Javascript
微信小程序上传图片功能(附后端代码)
Jun 19 Javascript
js的对象与函数详解
Jan 21 Javascript
js 获取扫码枪输入数据的方法
Jun 10 Javascript
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 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解析html类库simple_html_dom(详细介绍)
2013/07/05 PHP
php之readdir函数用法实例
2014/11/13 PHP
PHP跨平台获取服务器IP地址自定义函数分享
2014/12/29 PHP
laravel框架模型、视图与控制器简单操作示例
2019/10/10 PHP
javascript 弹出层组件(升级版)
2011/05/12 Javascript
input输入框的自动匹配(原生代码)
2013/03/19 Javascript
用JS在浏览器中创建下载文件
2014/03/05 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
javascript制作幻灯片(360度全景图片)
2015/07/28 Javascript
JS实现网页标题随机显示名人名言的方法
2015/11/03 Javascript
js如何判断输入字符串长度
2015/12/16 Javascript
React组件的三种写法总结
2017/01/12 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
2017/01/20 Javascript
react-redux中connect的装饰器用法@connect详解
2018/01/13 Javascript
详解使用VUE搭建后台管理系统(vue-cli更新至3.0)
2018/08/22 Javascript
Nuxt.js SSR与权限验证的实现
2018/11/21 Javascript
vue配置font-awesome5的方法步骤
2019/01/27 Javascript
Python中关键字nonlocal和global的声明与解析
2017/03/12 Python
解决python文件字符串转列表时遇到空行的问题
2017/07/09 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
python字典的常用方法总结
2019/07/31 Python
pytest中文文档之编写断言
2019/09/12 Python
python实现梯度法 python最速下降法
2020/03/24 Python
CSS3 display知识详解
2015/11/25 HTML / CSS
通过Canvas及File API缩放并上传图片完整示例
2013/08/08 HTML / CSS
英国内衣连锁店:Boux Avenue
2018/01/24 全球购物
澳大利亚领先的时尚内衣零售商:Bras N Things
2020/07/28 全球购物
Java提供了哪些企业应用编程接口
2015/02/13 面试题
大学军训感言1000字
2014/02/25 职场文书
煤矿班组长竞聘书
2014/03/31 职场文书
老干部工作先进事迹
2014/08/17 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
初中团支书竞选稿
2015/11/21 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
mysql 数据插入优化方法之concurrent_insert
2021/07/01 MySQL
详解如何使用Nginx解决跨域问题
2022/05/06 Servers