先上代码
var n = 1
function fn() {
var n = 2
function f() {
n--
console.log(n)
}
f()
//console.log(n) 可以在此处尝试调试n的值可以看出来n--影响了fn函数作用域里面的n值
return f
}
var x = fn()
x()
console.log(n)
//1 0 1
我们一步一步分析:
1.第一步 声明了一个x=fn(),那么此时会调用fn函数,fn内部又自己调用了一次f函数,f函数里面的n变量因为闭包特性能直接访问fn函数作用域里面的n,也就是此时fn函数里面的n是2,然后进行了n--,第一次输出的结果也就是1,此时n--操作改变的其实是fn函数作用域里面的n(关键),然后我们会将函数
function f() { n-- console.log(n) }返回给x
2.第二步我们运行了x(),也就是对f进行了调用,那此时f里面的n也是访问fn里面的n值拿到的,那么上面我们说到了第一次运行n--的时候改变了n在fn函数作用域里面的值,此时的n=1,当我们再次运行f里面的n--,那么调试n的值就是0了
3.第三步我们直接调试了全局变量里面的n值,但是我们从始至终都没有对全局变量的n进行重新赋值,就算fn函数作用域里面有一个同名变量n,但它处于函数作用域中且用var关键词声明的(要考虑变量前面没有关键词声明的情况和var变量提升的情况),并没有影响到全局作用域里面n,我们一直都是操作的函数作用域fn里面的变量n,所以全局变量n的值调试出来是1