<script>
//什么是闭包:就是函数作用域 --closure
//全局:global
/*
--函数出生时会自动保存所在的词法作用域,
词法作用域意思就是所在的作用域们
--词法作用域会被保存在scope中
--为什么保存在scope?
--因为这样可以保存函数原有的属性,方便在别的地方使用
---当听到闭包这个词的时候,就应该知道它是一个函数作用域,
被保存在另一个函数的scope中
*/
//查看函数scopes
//下面这个函数是生在全局中的,所以它的词法作用域就是window这个作用域
function a(){
}
//用console.dir查看scopes
console.dir(a);
//如果上面的函数不生在全局而是在别的作用域
{
let b=1997;
function c(){
//注意函数只会存对自己有用的作用域,如果下面
//没有输出b的话,函数不会把块级作用域存在scopes中
console.log(b);
}
}
console.dir(c);
/*
如果块级作用域中放一个函数,这个函数中再放一个函数
*/
{
let g=9;
function d(){
var f=999;
//d函数的作用域是e函数的闭包,
//e函数的闭包存在e函数的scopes属性中
function e(){
console.log(g,f);
}
console.dir(e);
}
d();
}
/*
简化代码解释闭包
注意:函数里面套函数,外层函数是里层函数的闭包
*/
(function (){
//自调用的函数中声明一个函数
var i=7;
function h(){
console.log(i);
}
//函数外打印输出这个函数
console.dir(h);
})()
</script>
闭包的作用
<script>
/*什么是静态函数--就是声明了一个函数没调用,
但是直接打印出来的就是静态函数*/
function a(){
return 111
}
console.log(a);
/*什么是动态函数--就是调用了的函数*/
function b(){
return 222
}
//问题:为什么直接b()调用不会出现return的222?
console.log( b());
/*
--闭包的缺陷:由于正常函数执行完会形成局部作用域对象
--当函数执行结束时,这个局部作用域对象会被销毁,来节省空间
--但是闭包机制会导致函数作用域被保存到另一个函数中,
--然后这个函数作用域就无法释放,导致内存的浪费
为了解决这个问题,es6版本就有了块级作用域来代替闭包
但是由于大家习惯了用闭包,所以闭包还是很常见
*/
/*
闭包的作用就是给函数提供私有变量,避免全局污染
*/
//例如:记录函数的调用次数
/*3.但是这个变量放在全局会造成全局污染*/
//4.解决方法:ES6之前是用匿名函数自调用给函数提供一个闭包
//6.return完之后还要用一个变量保存才行
var c=(function(){
var count=0;
function c(){
//1.由于函数调用完作用域就会销毁,所以要把声明的
//2.变量放在函数外
// var count=0;
count++;
console.log('调用了'+count+'次');
}
return c
})()
/*
5.问题:为什么会提示c函数未定义:因为外面不可以调用局部函数里面的东西
解决方法:要把函数里面的东西暴露给外面就要用return
*/
c();
c();
c();
c();
c();
console.dir(c);
</script>