<!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>函数--闭包</title>
</head>
<body>
<script>
/*
javascript函数--闭包:
全局变量可以通过闭包实现局部私有。
有权访问父作用域的函数,即使在父函数关闭后。
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。
也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。
在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
*/
/*
1.执行上下文
2.闭包
3.闭包用途
*/
//1.执行上下文
/*
js每段代码的执行都会存在于一个执行上下文环境中,而任何一个执行上下文环境会存在于整体的执行上下文中。
根据栈先进后出的特点,全局环境产生的执行上下文环境会先压入栈中,存在于栈底。
当新的函数进行调用时,会产生的新的执行上下文环境,也会压入栈中。
当函数调用完成后,这个上下文环境及其中的数据都会被销毁,并弹出栈中,从而进入之前的执行上下文中。
处于活跃状态的执行上下文环境只能同时有一个。
*/
var a= 10; //1.进入全局执行上下文环境(全活)
var fn = function (x) {
var c = 10;
console.log(c+x);
};
var bar = function (y) {
var b = 5;
fn (y+ b); //3.进入fun()函数执行上下文环境(fn()活)
};
bar (20); //2.进入bar()函数执行上下文环境(bar()活)
//2.闭包
/*
函数拥有的外部变量的引用,在函数返回时,该变量仍然处于活跃状态。
在js中存在一种内部函数,即函数声明和函数表达式可以位于另一个函数的函数体内,
在函数中就可以访问外部函数声明的变量,当这个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
消耗内存
*/
//1.进入全局执行上下文环境
function fn1 (){
var max = 10 ;
return function bar (x){ //3.进入bar (x)执行上下文环境
if(x>max){ //调用maxbar()不会被销毁
console.log(x);
}
};
};
var fl=fn1();
fl(11); //2.进入fn (x)执行上下文环境
//3.闭包用途
// 3.1计数器
/*
通过自调用函数add实现闭包
*/
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
//3.2结果缓存
/*
缓存一些数值
*/
var cachedBox = (
function(){
//缓存的容器
var cache={};
return{
searchBox:function(id){
//如果再内存中,则直接返回
if(id in cache){
return '查找结果为:'+cache[id];
}
//经过一段时间的dealFn函数处理
var result = dealFn(id);
//更新缓存的结果
cache[id]=result;
//返回计算的结果
return '查找的结果为:'+result;
}
};
}
)();
//处理很耗时函数
function dealFn(id){
console.log('这是一段很耗时的操作');
return id;
}
//两次调用
console.log(cachedBox.searchBox(1));
console.log(cachedBox.searchBox(1));
</script>
</body>
</html>