題目
var a = 0;
var b = 0;
function A(a) {
A = function (b) {
console.log(a + b++)
}
console.log(a++)
}
A(1); //1
A(2); //4
考點
- js作用域鏈的理解(全局作用域和函數(shù)作用域)
- ++a,a++兩種方式的區(qū)別
解讀代碼
A(1) 調(diào)用

- 第(1、2)是js的預處理機制
- 第(5)函數(shù)賦值會先在函數(shù)作用域內(nèi)找A變量,但是沒有找到,就向全局作用域找,找到了函數(shù)名為A這個函數(shù),并且賦給函數(shù)名A新的函數(shù),重置了函數(shù)A
- 第(6)在輸出a時,先會在函數(shù)作用域找,找到了參數(shù)a,就不會往上找
- 第(6)a++ 是先處理輸出再讓a自加
A(2) 調(diào)用
在A(1)調(diào)用之后,函數(shù)A已經(jīng)被重新賦值了,變成了function (b) {console.log(a + b++)},我們就稱這個函數(shù)為B吧

- 第(8)因為A函數(shù)在執(zhí)行A(1)時已經(jīng)被修改了,所以執(zhí)行的全新的函數(shù)
- 第(9)在js代碼編譯時就確定了作用域的范圍。因為函數(shù)B是在A里面定義的,使用B中找不到a變量,就會往A找(疑惑A為什么還沒有結(jié)束?涉及到作用域銷毀機制),在A中就找到了變量a(當前為2了)
后記
如果看不懂上面的某些內(nèi)容,說明你的函數(shù)作用域還沒有過關(guān)。