IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 理解JavaScript中的闭包 -> 正文阅读

[JavaScript知识库]理解JavaScript中的闭包

在理解闭包之前我们需要先了解以下知识:
作用域与作用域链
JavaScript执行环境
垃圾回收机制
在了解以上知识后,我们再来探讨闭包的知识。

什么是闭包

闭包是指有权访问另一个函数作用域中变量的函数;使用方:一般是在函数中再返回一个函数的,例如:

function closure(){
	return function(){}
}

举个实例来看一下,大家可以先算一下输出结果:

 let a = 0;
 let b = 0;
 let A= function(a){
     A=function(b){
         console.log(a++ +b)
     }
     console.log(a++)
 }
 A(1);
 A(2);

上面的函数虽然没有显式的返回一个函数,但是他也是一个闭包函数,因为内部的A函数是有权访问外部A函数的值的,其次A函数作为一个全局变量,在内部重新为其绑定函数后就相当于向外部返回了一个新的函数。该函数在执行过程中经过以下步骤:
1、程序开始执行,创建全局执行上下文(EC(G)),创建当前活动对象(VO(G)),VO(G)包括全局变量a = 0;b=0,A=外部A函数的指针位置。当前作用域为EC(G);
2、程序执行到A时,将会创建一个堆内存,该内存位置即为A函数指针位置,当前堆内存将包含:[[scope]] (作用域):EC(G),参数a,以及程序代码。
3、A(1)开始执行,此时将会创建一个函数上下文(EC(A1)),并创建当前活动变量:AO(A1),当前活动变量包括:a=1,A=内部函数A的指针位置,当前函数作用域链为:EC(A1)、EC(G)。函数执行完毕,输出1;
4、步骤3程序执行到A时,将会为A开辟一个堆内存,该内存包括:形参b,[[scope]]:EC(A1),以及函数内的代码。
5、步骤3执行完毕后,函数A中的形参a将变为2;形参a并未被销毁,在后续仍然可以访问。这是为什么呢?我们通过垃圾回收机制来看一下。此时外部A函数变成了内部的A函数,内部的A函数将会被放到全局,而内部A函数引用了外部A函数的形参,根据引用计数的原理,外部A函数的作用域将不会被销毁,将会被持续保存。
6、执行内部A函数,函数创建执行上下文(EC(A2)),创建活动对象(AO(A2)),a=2,b=1;输出结果为3;a将会变更为3。
7、继续执行A(x),,重复步骤6。

整个闭包中值得注意的是,当创建闭包后,函数的作用域在函数执行后没有被销毁。以上面的例子为例,内部的A将会替代外部的A指向一个函数,而内部的A在创建时就引用了外部函数的作用域,所以外部函数的引用将无法归0,外部函数的作用域也将不会被垃圾回收。

闭包的问题

正是由于闭包不会回收外部函数的变量,所以闭包也就容易引起内存泄漏。

闭包的作用

保护函数的私有变量不受外部的干扰。形成不销毁的栈内存。
保存,把一些函数内的值保存下来。闭包可以实现方法和属性的私有化

闭包的应用

1、函数作为参数

function out(){
	let a = "out";
	return function(){
		console.log(a)
	}
}
function f(fn){
	let a= "test";
	fn();
}
f(out()) // out

此时会输出out,这是因为fn就是out函数的返回函数,out的返回函数的作用域链的上级就是out。如果不在out中声明a,此时输出将会报错。这是由于参数具有自己单独的作用域。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 11:59:24  更:2021-07-26 11:59:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/22 23:54:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码