闭包以及闭包的基本原理

HTML基础

  • 闭包
    • 1.闭包的本质
    • 2.函数的深入了解
      • 2.1. 封装
      • 2.2 调用执行
      • 2.3 函数执行开始
      • 2.4 函数执行结束
    • 3 闭包的基本原理1
    • 3 闭包的基本原理2

闭包

1.闭包的本质

在函数外部,调用操作函数,函数内部的数据。

	为了保护数据的安全性 
		全局变量容易造成全局变量污染
		为了确保数的安全性,会将重要的数据,定义为局部变量
		再通过闭包的形式,调用使用函数的内部数据。

2.函数的深入了解

2.1. 封装

		(1)在 内存的 堆 中 开辟一个存储空间
				操作系统给这个存储空间赋值内存地址
				存储空间准备存储 函数程序
		(2)函数程序 以 字符串形式 存储在存储空间中 
		(3) 函数名称 / 变量名称 存储在 内存的 栈 中
		(4)函数名称 / 变量名称 中 存储的是 函数的内存地址

2.2 调用执行

		(1)通过 栈 中的 函数名称 /  变量名称 中 存储的内存地址
				找到 堆  中的  存储空间 调用其中存储的函数的代码程序
		(2)给 函数的形参 赋值 实参
		(3) 预解析 / 预编译 / 预解释  函数的程序
		(4) 执行 函数程序代码

2.3 函数执行开始

	在 堆 中 函数的存储空间中
	再 开辟一个独立的 内存空间 称为 执行空间
	专门 存储 函数执行时 需要的 形参 变量 等

2.4 函数执行结束

	执行空间自动 销毁 / 释放
	执行空间中存储的 形参 变量 等 也会一起 销毁 /  释放
	这个过程被称为 JavaScript 内存回收机制 / 内存释放机制 / 内存管理机制……

3 闭包的基本原理1

	不能调用 函数内部数据的原因是 
            函数执行结束 执行空间就会被释放 其中存储的 形参和变量 也会被释放
            如果 要 操作调用 函数内部的 形参和变量 
            就 需要 执行空间 不会被 销毁/释放
            生成 一个 不会被 销毁/释放 的 执行空间 原理
            函数的返回值 是一个 引用数据类型
function fun1(){
    let int = 100 ;
    return int ;
}
	// res1 中 存储的是 函数fun1 的 执行结果返回值 
	// 也就是 return 的 变量int中 存储的 数据数值 100 
let res1 = fun1();
function fun2(){
	const arr = [100,200,300,400];
	return arr ;
}
	// res2 中 存储的是 函数fun2 的 执行结果返回值
	// 也就是 return 变量arr中 存储的 数组的内存地址
	// 数组arr 的 内存地址 在 函数外 被 变量存储
	// 也就是 数组arr 在 函数外 被 使用
	// 此时 函数的执行空间 不会被 销毁/释放
	// 但是 此时 还不能直接 操作 变量arr
	const res2 = fun2();

3 闭包的基本原理2

/* 

1,  定义一个函数A   

      在这个函数A中 定义的 形参/变量 
      是 实际程序中 全局变量 
      为了 防止全局变量污染 
      定义成 函数内的 形参/变量 也就是 局部变量

2,  函数A 的 return返回值 是一个 匿名函数

     这个 匿名函数 操作调用 函数A中 
     被保护的 全局变量 

3,  在 函数A 外 调用函数A 并且使用 变量储存 函数A的调用结果

     变量中存储的是 函数A的执行结果返回值 
     也就是 return 的 匿名函数

4,  调用执行变量 也就是在 调用执行 函数A return的返回值 匿名函数
     也就是 在 操作调用 函数A 中 被保护的全局变量 

        
总结:
    为什么必须要写成return匿名函数的语法形式

    如果多次 直接调用函数 
    每次 变量 都会被 重新定义重新赋值 永远是原始数值

    如果多次 通过 return的匿名函数 操作 变量
    变量只有第一次会被 调用执行一次 
    之后每次都 只是 操作变量 
    没有 再次调用 整个函数 也就是没有 再次重新定义变量 重新赋值

    每次调用的数据 都是 不同的数值数据

*/

这里我们来看一个例子

// 定义一个函数 存储 变量int赋值100 

function fun(){
  	// 数据定义为函数内部 不会被全局变量污染 数据就安全了
let int = 2 ;
	// 函数的返回值 是一个 匿名函数
	// 因为 return 的是一个 引用数据类型 
    // 执行空间 就不会被 销毁/释放  变量int 和 return的匿名函数就会一直存在
return function(){
    // 匿名函数的程序内容 是 操作调用 写在函数内的 全局变量 

int *= 2 ;

if( int > 500 ){
	console.log(111);
}else{
	console.log(222);
		}                   
	}
}

// res 中 存储的是 函数fun的返回值 也就是 return的 匿名函数
const res = fun();
console.log( res );

// 调用 变量() 就是 执行调用 匿名函数 
// 也就是 对 变量int 数据的操作调用
res();

你可能感兴趣的:(javascript,函数闭包,前端)