关于JS闭包的一个疑惑

        function f1() {
            var n = 999;
            f2 = function () {
                n += 1;
                console.log(n);
            }
        }
        f1();
        f2();

如上代码中,定义了一个函数f1,内部又定义了一个匿名函数(也就是闭包),并且赋值给f2,按理来说,f2前面不是要加var标示来声明一个变量吗?但是我加上var后,却报错了,提示错误:f2 is not defined。为什么呢?另外,为什么上面代码在全局环境中能够访问在f1内部定义的f2?一共两个疑惑,先谢了。

阅读 2.7k
4 个回答

你的两个疑惑其实都是一个问题。
f2没有写var的时候,相当于定义了一个全局变量,所以你当然可以在外部访问f2;
f2写上var之后,它就成了f1私有的了,当然就不能在外面访问f2啦。

我们来逐一解答:
(1)问题:

    f2前面不是要加var标示来声明一个变量吗?但是我加上var后,却报错了,提示错误:f2 is not defined
原因: 
    因为在方法f1中写的方法f2不写var 就把f2提升作用域为全局了,就相当于你在最外面定义了一个var f2; 
    然后又在f1函数中赋值f2;  如何你在f1中给 f2加上了var,那是定义局部变量,只有在f1函数中能访问到。
    在f1外面是访问不到的,最终就会报错 f2 is not defined。

(2)问题:

    为什么上面代码在全局环境中能够访问在f1内部定义的f2
  原因: 
    我在问题(1)中已经回答了,因为提升了作用域,建议你用 eslint 进行语法检查,
    这样会提高你的代码质量。排除不必要的潜在问题。 

你这个跟闭包也没啥关系,关键是你f1没有返回f2。
你需要了解一下作用域的知识。不给f2加var,f2就成了全局变量,跟下面的代码一个意思

var f2;
function f1() {
    var n = 999;
    f2 = function () {
        n += 1;
        console.log(n);
    }
}
f1();
f2();

当加上var之后,f2成为了局部变量,你当然就访问不到了。
你想了解闭包你的代码应该写成这样:

function f1() {
    var n = 999;
    f2 = function () {
        n += 1;
        console.log(n);
    }
    return f2;
}
var f2 = f1();
f2();
f2();
f2();

加了var 就是局部变量 不加就是默认挂在全局
f2之所以能执行那是因为你是把函数以变量赋值的形式 如果改为function f2(){} 这样就不行了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题