闭包
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
</style>
</head>
<body>
<div id="box"></div>
<ul class="list">
<li>link1</li>
<li>link2</li>
<li>link3</li>
<li>link4</li>
<li>link5</li>
</ul>
</body>
<script>
// 函数:
// 函数在定义时,存在一个位置,当前函数的定义作用域
// 函数在执行时,存在一个位置,当前函数的执行作用域
// 定义作用域和执行作用域,都不是当前函数自身内部,而是当前函数所处的位置
// function box(){
// function fn(){
// }
// fn();
// // fn的执行作用域,是box的局部作用域
// }
// box的定义作用域,是全局作用域
// fn的定义作用域,是box的局部作用域
// box();
// box的执行作用域,是全局作用域
// fn(); 执行不了
// function fun(){
// box();
// // box的执行作用域,是fun的局部作用域
// }
// 执行作用域是固定的么?是不是只能在哪定义,就在哪执行
// 可以跨作用域,局部可以执行全局
// 函数是一种特殊的对象,意味着,函数类型属于引用数据类型
// 默认浅拷贝
// 如果通过简单赋值,复制一个函数,得到的其实还是原函数
// ================ ==================
// function box(){
// function fn(){
// }
// return fn;
// }
// var obj = {};
// obj.show = box;
// obj.show();
// 在box中返回了一个函数,返回值被f变量保存,因为函数也是对象,简单赋值属于浅拷贝
// 那么其实当前的f就是box中返回的那个函数的一个引用
// 如果将f作为函数执行了,相当于执行了box返回的那个函数的引用,其实就是执行了box里面的函数
// var f = box();
// f();
// 当前变量f,其实就是box内部的fn,的执行作用域,就变成了全局
// ========================
// 函数的定义作用域,是固定的,写在哪就是哪
// 函数的执行作用域,是可变的,在哪执行就是哪
// 函数在执行时,可以拿到当前函数所在定义作用域中的所有数据
// function box(){
// var a = 10;
// a++;
// console.log(a);
// }
// box(); // 11
// box(); // 11
// box(); // 11
// box(); // 11
// function box(){
// var a = 10;
// function fn(){
// a++;
// console.log(a);
// }
// return fn;
// }
// var f = box();
// f();
// f();
// 闭包:利用函数的嵌套,实现将第一层函数中的局部变量,可以在第一层函数外部修改的过程,叫闭包
// =======================
// 简单
// 闭包的形成环境:
// 函数的嵌套
// 内部函数使用外部函数中的变量
// 将内部函数返回,在外部函数的外部,接收返回值,执行(相当于执行了内部函数)
// 闭包的特点:
// 1.解决掉所有的全局变量,节省内存空间
// 2.可以在函数外部,修改函数内部的变量(外部修改内部,安全么?)
// 3.相对于局部变量来说,浪费了内存
// 按需使用
// =======================
// 闭包的应用场景:
// 1.循环中的事件,事件处理函数中使用了循环的每次的计数器
// var ali = document.querySelectorAll(".list li");
// for(var i=0;i<ali.length;i++){
// // (function(index){
// // ali[index].onclick = function(){
// // console.log(index);
// // }
// // })(i);
// ali[index].onclick = (function(index){
// return function(){
// console.log(index);
// }
// })(i);
// }
// 闭包并不是一种固定写法,而是一种场景,只要满足了三个条件,就是闭包
// 2.给某些系统默认的回调函数,传参
// (给计时器的回调函数,传参)
// function fn(a){
// return function(){
// console.log(a);
// };
// }
// setTimeout(fn("world"), 1000);
// 3.处理掉全局变量,只要开启新文件,新功能,最好上手就是一个匿名函数,简易闭包
// var f = (function(){
// var a = "hello";
// function fn(){
// console.log(a + "world");
// }
// return fn;
// })();
// f();
// 如果当前功能只是一个封装,不只是在当前使用,将来在其他位置也会使用,或者给别人使用
// 模块化开发
// 4.回想:封装过的事件委托,利用到了闭包
// obox.onclick = eveEnt(achild,function(){})
// function eveEnt(eleArr,cb){
// return function(eve){
// eleArr
// cb
// }
// }
// =======================
// 拓展:计算机的垃圾回收机制
// 硬盘的:存储空间,删除数据,先转到某个空间中(回收站),可以找回来
// 内存的:运行空间,删除数据,直接删除,找不回来
// 闭包:就是利用作用域的嵌套,触发计算机的垃圾回收机制
// 私有变量:函数内部的变量,在外部修改
// 闭包:就是利用作用域的嵌套,将局部变量进化成私有变量的环境
// 函数的高级应用
</script>
</html>