// 创建不被销毁的执行空间
// 要利用 return
// 一般情况下, return 如果返回的是一个基本数据类型
function fun1(){
var a = 100;
var b = 200;
return a+b;
// return 返回的是 a+b 的执行结果,也就是数值300
// 数值 300 计算之后,与变量a和变量b没有任何关系
// 即时 执行空间被销毁, 数值300 已经作为返回值,返回了,不会影响程序的执行结果
}
// 变量res 存储的是 fun1()的返回值 是 a+b 的结果 数值300
// 变量a和变量b被销毁,对返回值300没有影响的
let res = fun1();
function fun2(){
const obj = {
name:'张三',
age:18,
}
// return 返回的实际是,obj变量中存储的对象的内存地址
return obj;
}
// 变量 o 中 存储的 是 obj对象的内存地址
// 如果执行空间被销毁, obj 被销毁,o中存储的内存地址,就失去意义了
// 如果 函数的返回值 return 的是一个 引用数据类型的内存地址
// 并且 在函数之外,有其他的变量存储这个内存地址
// 函数的执行空间,就不会被销毁,就会一直存在
const o = fun2();
// 不会销毁的执行空间的存在条件
// 1,函数的返回值是一个引用数据类型
// 2,在函数外,有另一个变量,在存储返回值
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
const oLis = document.querySelectorAll('ul>li');
// for(let i = 0 ; i <= oLis.length-1 ; i++ ){
// oLis[i].addEventListener('click' , function(){
// console.log(i+1);
// })
// }
for(var i = 0 ; i <= oLis.length-1 ; i++ ){
fun(i);
}
function fun(num){
oLis[num].addEventListener('click' , function(){
console.log(num+1);
})
}
// let 声明 变量i 可以完成需要的效果
// 原因: 每次执行循环,都会生成一个独立的,存储独立数据的循环变量 i
// 点击时,调用i 不同的标签,触发的点击事件,执行时,i对应的是不同数值
闭包的特点 优点,同时也是缺点
1, 函数的执行空间不会被销毁
优点 : 空间中的内容,会一直存在
缺点 : 会占用内存空间,降低执行效率
2, 可以从函数外部调用函数内部的数据
优点 : 数据使用便捷
缺点 : 容易造成数据泄露,不安全
3, 保护局部作用域变量不被销毁
优点 : 局部作用域变量不被销毁
缺点 : 占用存储空间,容易内存泄露
闭包的重要性:
闭包看似是一个为了调用函数内,局部作用域变量的方法
实际上,是为了 防止 全局变量污染 的一个手段
全局变量污染
定义变量分为全局作用域变量和局部作用域变量
全局作用域变量特点:任意一个函数都可以调用修改这个变量存储的数据数值
如果一个全局作用域变量,被不应该操作的函数,修改了存储的数据,就称为全局变量濡染
为了防止全局变量污染,可以使用一个函数,将变量定义为局部作用域变量
其他函数的操作,就不会影响到这个变量存储的数据了
但是又产生了新的问题,定义在函数内部的局部作用域变量,无法在函数外部被直接使用
可以使用闭包,让,局部作用域变量,可以在函数外部被调用,被使用