Lidemy / mentor-program-2nd-futianshen

mentor-program-2nd-futianshen created by GitHub Classroom
14 stars 2 forks source link

Hoisting 宣告提升 #12

Open futianshen opened 6 years ago

futianshen commented 6 years ago

宣告提升 Hoisting

理解 Hoisting 這個概念可以學到什麼?

為什麼要設計宣告提升的機制?

讓 Variable 和 Function 還沒宣告就可以使用。

宣告分為兩個階段

只有宣告沒有賦值,變數的值就是 undefined。 只有賦值沒有宣告,變數會在 Global Scope 做宣告。

提升步驟

  1. 將作用域內的「宣告」全都放到作用域的最上方,「函式」的宣告優先於「變數」的宣告。
  2. 最內層的 scope 先 hoist,變數在 scope 內已經宣告過則直接忽略。如果變數在 scope 內還沒有宣告,往外層繼承變數的數值,如果外層沒有就繼續往外層找,直到找到全域。(和程式執行的 Call Stack 資料結構有關 )
  3. 如果 變數 和 function 用相同的名字,誰先宣告誰先用。(這點好像有問題 例題3,8)(function 和 variable 誰先拿到最上面?)

例題

  1. 執行出來的結果會是什麼? 1
test()

function test() {
    console.log(1)
}
  1. 執行出來的結果會是什麼? is not a function
    因為只有變數 test 有提升, function 是一個函式表示式(匿名函式)(有名字的人才會被點出來?)
    
    test()

var test = function() { console.log(1) }

3. 執行出來的結果會是什麼?
   function

``` js
console.log(test)
var test =10

function test() {
    console.log(1)
}
  1. 執行出來的結果會是什麼? 2
    
    test()

var test = 10 function test() { console.log(1) } function test() { conosle.log(2) }


5. 執行出來的結果會是什麼?
   10
``` js

function test(a) { 
    console.log(a)
    var a = 30
}
test(10)
  1. 執行出來的結果會是什麼? has already been declared

function test(a) { console.log(a) let a = 30 } test(10)


7.  執行出來的結果會是什麼?
   function

``` js 
function test(a) { //before
    console.log(a)
    var a = 30
    function a() {
    }
}
test(10)
function test(a) { //after
    function a() {}
    console.log(a)
    a = 30
}
test(10)
  1. 執行出來的結果會是什麼? undefined
function test(b) { // before
    console.log(a)
    var a = 30
    function b() {
    }
}
test(15)
function test(b) { // after
    function b() {}
    var a
    console.log(a)
    a = 30
}
test(15) // 問題:如果裡面有設定名字是 b 的 function 那還會引入外面的變數嗎?
  1. 執行出來的結果會是什麼? undefined

    function test(d) { //before
    var d = 20
    function test2(c) {
        console.log(d)
        var d = 30
    }
    test2(15)
    }
    test(10)
    function test(d) { // after
    var d = 20
    function test2(c) {
        var c =15
        var d
        console.log(d)
        d = 30
    }
    test2(15)
    }
    test(10)
  2. 執行出來的結果會是什麼? 20

    function test(d) { // before
    function test2(c) {
        console.log(d)
    }
    var d = 20
    test2(15)
    }
    test(10)
    function test(d) { // after
    var d
    function test2(c) {
        var c = 15
        console.log(d)
    }
    d = 20
    test2(15)
    }
    test(10)
  3. 執行出來的結果會是什麼? 10

    function test(d) { // before
    function test2(c) {
        console.log(d)
    }
    test2(15)
    var d = 20
    }ß
    test(10)
    function test(d) { //after
    var d = 10
    function test2(c) {
        var c = 15
        console.log(d) 
    }
    test2(15)
    d = 20
    }
    test(10)
  4. 執行出來的結果會是什麼? a is not defined

    function test() {
    console.log(a)
    let a = 1
    }
    test()
  5. 執行出來的結果會是什麼? 1

    function test() {
    let a = 1
    function test2() {
        console.log(a)
    }
    test2()
    }
    test()
  6. 執行出來的結果會是什麼? undefined

    function test() { //before
    let a = 1
    function test2() {
        console.log(a)
        var a = 10
    }
    test2()
    }
    test()
    function test() { //after
    let a = 1
    function test2() {
        var a
        console.log(a)
        a = 10
    }
    test2()
    }
    test()
  7. 執行出來的結果會是什麼? a is not defined

function test() {  // before
    let a = 1
    function test2() {
        console.log(a)
        let a = 10
    }
    test2()
}
test()
function test() {  // after
    function test2() {
        // Temporal Dead Zone var 是 undefined 用let 是 not defined
        console.log(a)
        a = 10
    }
    test2()
}
test()

參考資料

延伸閱讀

《我知道你懂 hoisting,可是你了解到多深?》