(function(){
var name="hello";
var fn1= function(){
return name;
}
//直接在自执行函数里面调用fn2,将fn1作为参数传入
fn2(fn1);
})()
function fn2(f){
//将函数作为参数传入
console.log(f());//执行函数,并输出
}
3.4 定义私有变量
var Foo = function(){
var name = 'apple';
this.getName = function(){
return name;
};
this.setName = function(str){
name = str;
};
};
var foo = new Foo();
foo.name; // undefined, name是私有变量, 无法直接访问
foo.getName(); // 'apple'
foo.setName('banana'); // name changed to 'banana'
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar is now a closure.
bar(10); // will also alert 16
bar(10); // will alert 17 because tmp increased 1
1 什么是闭包
闭包也是函数——闭包函数。作为内部函数保持着对外部函数变量的引用。最终总结一下,闭包就是能够引用其他函数内变量(作用域)的函数;
由于在JS中,变量的作用域属于函数作用域,在函数执行后作用域就会被清理、内存也随之回收,但是由于闭包是建立在一个函数内部的子函数,由于其可访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁,这时的子函数——也就是闭包,便拥有了访问上级作用域中的变量的权限,即使上级函数执行完后作用域内的值也不会被销毁。
2 闭包解决了什么?
在本质上,闭包就是将函数内部和函数外部连接起来的一座 桥梁。
由于闭包可以缓存上级作用域,那么就使得函数外部打破了 “函数作用域” 的束缚,可以访问函数内部的变量。以我们经常见到的使用的 Ajax 成功回调为例,这里其实就是个闭包,由于上述的特性,回调就拥有了整个上级作用域的访问和操作能力,极大的提高了便利。开发者不用去写钩子函数来操作上级函数作用域内部的变量了。
3 闭包有哪些应用场景?
简而言之,无论使用何种方式对函数类型的值进行传递,当函数在别处被调用时都有闭包的身影。
3.1 return 一个函数
解释:这里的 return f, f()就是一个闭包,存在上级作用域的引用。
3.2 函数作为参数
解析:使用
return fo
返回回来,fo()
就是闭包,f(foo())
执行的参数就是函数fo
,因为fo()
中的 a 的上级作用域就是函数foo(),所以输出就是foo3.3 IIFE(自执行函数)
3.4 定义私有变量
这是一个闭包的常见应用,bar是一个foo返回的内部函数,bar使用了变量tmp,所以局部变量tmp不会被销毁,而且每次调用bar都会导致tmp数字加1.
3.5 循环赋值 - 拿到正确的值(老掉牙的问题了😝)
原理:声明了10个自执行函数,保存当时的值到内部。
参考