1. console.log(a) // undefined
  2. {
  3. a = 0
  4. function a () {}
  5. a = 1
  6. }
  7. console.log(a)

常规解释

  1. 根据阮一峰教程解释

OR41)]%({2}LTW~@B){E4{K.png

  1. 上面那种解释其实是有点不正确的
    1. var a = 0;
    2. if (true) {
    3. console.log(a, window.a) // function a () {} 0,提升仍然存在
    4. a = 1
    5. console.log(a, window.a) // 1 0,a = 1 赋值了块级作用域内的 a
    6. function a () {}
    7. console.log(a, window.a) // 1 1,非严格模式下上面那句函数声明将块级作用域里的 a 赋值给了外面
    8. a = 21
    9. console.log(a) // 21
    10. }
    11. console.log(a) // 1
    如果还觉得不过瘾,可以这么玩:
    1. let _a = 0;
    2. Object.defineProperty(window, 'a', {
    3. get() {
    4. return _a
    5. },
    6. set(val) {
    7. console.log('set a =', val)
    8. _a = val
    9. },
    10. enumerable: true,
    11. configurable: true
    12. })
    13. eval(`
    14. if (true) {
    15. console.log(a, window.a) // function a () {} 0
    16. a = 1;
    17. console.log(a, window.a) // 1 0
    18. function a () {} // set a = 1,没错这玩意能触发 setter……
    19. console.log(a, window.a) // 1 1
    20. a = 21;
    21. console.log(a, window.a); // 21
    22. }
    23. console.log(a); // 1
    24. `)

    知乎上面的解释

    https://www.zhihu.com/question/433134533
    https://www.zhihu.com/question/404772996/answer/1329363707