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 表单进行客户端验证demo
Aug 24 Javascript
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
jQuery的强大选择器小结
Dec 27 Javascript
浅析JavaScript Array和string的转换(推荐)
May 20 Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
Oct 10 Javascript
JS判断是否手机或pad访问实现方法
Dec 09 Javascript
原生js实现旋转木马轮播图效果
Feb 27 Javascript
JS排序之选择排序详解
Apr 08 Javascript
jQuery实现判断上传图片类型和大小的方法示例
Apr 11 jQuery
浅谈对于“不用setInterval,用setTimeout”的理解
Aug 28 Javascript
使用layui的layer组件做弹出层的例子
Sep 27 Javascript
js+canvas实现画板功能
Sep 13 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数组最大值,最小值的代码
2011/10/31 PHP
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
2014/06/05 PHP
PHP数组与对象之间使用递归实现转换的方法
2015/06/24 PHP
Redis使用Eval多个键值自增的操作实例
2016/11/04 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
Avengerls vs Newbee BO3 第三场2.18
2021/03/10 DOTA
Use Word to Search for Files
2007/06/15 Javascript
PNGHandler-借助JS让PNG图在IE下实现透明(包括背景图)
2007/08/31 Javascript
jQuery表单获取和失去焦点输入框提示效果的实例代码
2013/08/01 Javascript
javascript实现页面内关键词高亮显示代码
2014/04/03 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
jquery动画效果学习笔记(8种效果)
2015/11/13 Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
2016/06/08 Javascript
微信小程序进行微信支付的步骤昂述
2016/12/01 Javascript
bootstrap模态框实现拖拽效果
2016/12/14 Javascript
canvas绘图不清晰的解决方案
2017/02/28 Javascript
在vue项目中引入highcharts图表的方法(详解)
2018/03/05 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
vue实现商品加减计算总价的实例代码
2018/08/12 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
搭建基于express框架运行环境的方法步骤
2018/11/15 Javascript
vue实现select下拉显示隐藏功能
2019/09/30 Javascript
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
Python处理命令行参数模块optpars用法实例分析
2018/05/31 Python
在Pycharm中执行scrapy命令的方法
2019/01/16 Python
全网最全python库selenium自动化使用详细教程
2021/01/12 Python
CSS3属性box-sizing使用指南
2014/12/09 HTML / CSS
亚洲独特体验旅游专家:eOasia
2018/08/15 全球购物
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
eBay奥地利站:eBay.at
2019/07/24 全球购物
英国钻石公司:British Diamond Company
2020/02/16 全球购物
学校交通安全责任书
2014/08/25 职场文书
2014幼儿园教育教学工作总结
2014/12/17 职场文书
小学少先队活动总结
2015/05/08 职场文书
城镇居民医疗保险工作总结
2015/08/10 职场文书
前端框架ECharts dataset对数据可视化的高级管理
2022/12/24 Javascript