1、为什么要使用闭包?
- 可以读取函数内部的变量
- 让变量是始终保存在内存中
2、如何形成闭包?
- 函数内部嵌套函数
- 内部函数引用外部函数中的变量
- 参数和变量不会被回收
- 外部函数的返回值是内部函数名
3、案例
案例一:体现局部变量执行之后就会销毁
前提知识:js解析代码由上至下、从左至右执行
由此可见:每执行一次 都会从10开始 可知,上一行代码的函数调用执行的 - - 并没有生效
function test() { var a = 10 a-- console.log(a); } test() //9 test() //9 test() //9
案例二:体现闭包函数变量不会被销毁
思路:
- 外部函数A的返回值为内部函数名test
- 使用全局变量res接收A()的返回值 即等价于 var res=test
- 执行res( )等价于执行test() 而它存在于A()中,所以A()也被迫执行,而内部函数test使用了外部函数a变量,所以a变量不会被销毁
// // 实现一个函数每调用一次 变量递减 function A() { var a = 10; function test() { a--; console.log(a); } return test } var res = A() //全局res 接收值 因此不会被销毁 res() //9 res() //8 res() //7
案例三:作用域、闭包经典面试题
1、思路:
- 定义全局变量x接收fn()的返回值
- 执行x()等价于执行bar()
- a往祖宗上找到a=10,b往祖宗上先找到fn()作用域的b=20
- 函数外部的b=200,并不会对函数内部造成影响 所以a+b=30
var a = 10 function fn() { var b = 20 function bar() { console.log(a + b) //往父级找 } return bar } // var一个全局变量接收函数,在调用 var x = fn() //fn() 返回的是 bar var b = 200 x() //此时x()==bar() //30
案例四:闭包+this指向
思路:this存在于say()方法的返回函数中,this在全局中x()调用,所以this指向全局,全局中有 name=‘window’
name = 'window' //var name 代表当前作用域不是node中的全局作用域 var obj = { name: 'obj', say: function () { return function () { console.log(this.name); } } } var x = obj.say() x() //window