<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/* 闭包 函数内返回一个函数 出来 */
function fn() {
let a = 1//本应该销毁的局部变量
/* a被保留下来 但是函数外仍然不能访问
a相当于这个函数的私有变量 保证变量不会被污染 因为重名的情况 */
function fn1() {
a++//这个a就会一直存在 不会被销毁掉
console.log(a)
}
return fn1;
}
// 函数的作用域
/* 返回一个函数
函数内有原来函数的局部变量 */
// let abc = fn();
/* 两个函数嵌套 执行外部函数返回内部函数存储为变量
内部函数有权访问外部函数的局部变量 并保留不会被销毁 */
// abc()
// abc()
// abc()
// abc()
/* 闭包的特征:
1、具备独立的私有变量 ,私有变量之能在某个作用域内访问 并且可以长期存储 (类似于php中的static变量)
局部变量 只能在某个作用域(函数)内访问 但是不能长期存储
2、防止变量污染,防止名字冲突
3、容易造成内存泄漏
*/
/* 闭包的用途:
防止变量污染 */
// IIFE 自执行函数
// let utils = (
// function(){
// let aa = 100;
// return {
// ce:function(){
// aa++
// console.log(aa)
// }
// }
// }
// )();
// utils.ce();
// 闭包用于私有的存储
function fn1(){
this.a++;
this.b = 100
console.log(this)
}
let obj = {
a:100
}
// let fns = fn1.bind(obj);//bind 返回一个函数
// fns();
function fn2(_a,_b,_c){
this.a = _a;
this.b = _b
this.c = _c
return this;
}
/* 各种方法重构 重写 哈哈哈
参数也是局部变量*/
function binds(fn,obj){
// 内部函数只要使用的变量都不会被销毁了
// 闭包中 内部函数使用了外部函数的局部变量 ,此变量就不会被销毁
return function(){
arguments
// fn.call(obj);
return fn.apply(obj,arguments)
}
}
// binds(fn1,obj)();
let oobj = binds(fn2,obj)(100,100,200);
</script>
</body>
</html>