最近看到一道题挺有意思,话不多说,直接上题目:
var a = 0,
b = 0;
function A(a) {
A = function (b) {
console.log(a + b++);
};
console.log(a++);
}
A(1);
A(2);
console.log(a);
console.log(b);
输出结果:
1
4
0
0
题目解析: 这段代码的行为可能会让初学者感到困惑,因为它涉及到函数重定义和闭包的概念。让我们逐步分析这段代码的执行过程。
首先,定义了两个全局变量 a 和 b,但在这段代码中,全局变量 b 实际上没有被使用。
接着,定义了一个名为 A 的函数,它接受一个参数 a。但是,在函数体内,A 被重新定义为一个新的函数,这个新函数接受一个参数 b 并打印 a + b++ 的结果。这里有几个关键点需要注意:
- 当
A第一次被调用时(A(1);),它首先执行原始定义的函数体,其中console.log(a++);会打印出1(因为参数a传递的是1),然后a的值会增加到2(但由于这是参数a,它不会影响全局变量a的值)。 - 在原始函数体内,
A被重新定义为一个新的函数,这个新函数会捕获外部函数(即原始A函数)的局部变量a的值。由于 JavaScript 的闭包特性,这个新函数中的a将保持为2(即原始A函数被调用时参数a的最终值)。 - 当
A第二次被调用时(A(2);),由于A已经被重新定义为一个新的函数,所以它将执行这个新函数的逻辑。这个新函数会打印a + b++的值,但这里的a是闭包中捕获的2,而b是新函数的参数,传递的是2。因此,它会打印2 + 2 = 4,然后b的值会增加到3(但这个值在函数外部是不可见的,因为它只存在于新函数的局部作用域中)。