今天我看了一篇关于面试题的推文,结果感觉确实挺有难度的,我只看到了题目和答案,没看到解析。现在想明白了一道题,我来解析给大家看看。
题目如下:
var a = 0,
b = 0;
function A(a) {
A = function (b) {
console.log(a + b++)
}
console.log(a++)
}
A(1)
A(2)
答案是:先给你一点时间,自己思考哦~
5
4
3
2
1
答案揭晓:1 4
下面来谈一下我对这道题的理解吧。
首先,这里声明了两个全局变量a,b,初始值都是0。(虽然这里换行了,而且JavaScript有“自动加分号”的规则,但是a=0后面有逗号,这样是不会加分号的,它们仍然是同一句)
var a = 0,
b = 0;
然后,来看这里,这是本题的重点。
function A(a) {
A = function (b) {
console.log(a + b++)
}
console.log(a++)
}
外面的function A是函数声明,声明了全局函数A。
里面给A赋值了,注意,里面的“A”前面没有var或者let或者const,所以是在给A赋值,而A函数里面没有声明A变量,所以是给全局变量,或者说是“全局函数A”赋值了。
A(1)
A(2)
最后,调用了两次A函数。
过程是这样的:
一开始,代码初始化完了,A函数并没有被执行,在它被执行之前,它并没有被重新赋值,因此第一次调用A的时候,调用的是外层的A函数。
所以,外层的a函数接受参数a,a为1。
然后,给A重新赋值,A变成了里面的函数。
接着,继续执行外层的A函数,所以输出了a,输出的是1。(这里的++在后面,因此先输出a,后让a自增,a变成了2)
第二次调用A,调用的就是内层的A函数了,接受的参数是b,b等于2。
虽然A函数变成里面这个了,但是里面这个A使用到了外层函数的a参数,所以外层函数作为闭包,保留了a参数。
最后输出a + b++,相当于输出a+b。b是2,a也是2,所以输出4。
最后说一下我个人的看法:
我一开始在做的时候,看到里面给A赋值了,我第一反应是,既然覆盖了A,那A就是里面那个啊,管外面的干嘛?后来才反应过来,A第一次执行之后才会被覆盖,因此第一次执行的是外层的A函数,赋值以后再输出a参数,并且让a自增。我是后来打断点调试,然后发现第一次输出在下面一行,第二次输出在上面一行才恍然大悟。
遇到不懂的问题,也可以跟我一样打断点,进行观察和推理呀。