淺談JavaScript 函數做用域當中的「提高」現象

在JavaScript當中,定義變量經過var操做符+變量名。可是不加 var 操做符,直接賦值也是能夠的。
例如 : message = "hello JavaScript ! " 即定義了一個全局變量message,並賦值 「Hello JavaScript!」
--《JavaScript高級程序第三版》瀏覽器

如同往日通常,一羣人在所謂的技術交流羣裏面相互鬥圖着。忽然老王莫名的正經起來,在羣裏發了一道JavaScript的題目,讓你們猜一猜這道題的答案。編輯器

var foo = 1;
    function bar() {
        foo = 10;
        return;
        function foo() {}
    }
    bar();
    console.log(foo);  //求控制檯輸出多少?

看到這到題目以後,馬上不加思索回答了「10」。
首先第一步定義一個全局變量foo = 1,而後函數執行的時候又定義全局變量 foo = 10覆蓋了以前的全局變量,return以後,這個函數就直接結束, function foo {}來不及定義。所以控制檯輸出10;
按照在《高三》上面看到知識點推斷,毫無問題,簡直完美呀!函數

給本身32個贊!
【給本身32個贊!】學習

可是,在把答案發出去以後。本能就感受這道題不可能這麼簡單,不正經的羣忽然討論正經的代碼,確定會有大坑等着人來跳。一種很差感受涌上心頭,感受本身又要被打臉了。測試

趕忙打開編輯器測試一下這段代碼,手哆嗦的按下F12.只見控制檯下,一個耀眼的1赫然闖入眼簾。啪啪啪!!這臉又被打的,好疼呀!!code

爲何被打臉的老是我!!
【爲何被打臉的老是我!!】blog

果不其然羣里老王立刻的在羣裏否決個人答案,啪的一下打了這張老臉。
不行!這個臉打了得把場子找回來,這個老王接下來確定會揭曉答案並公佈解題思路。得在他公佈以前,講答案和緣由給測試出來。ip

通過簡單的測試以後,發現原來是後面的foo,函數提高到最頂端了。因此後面foo = 10中的foo其實是一個局部變量了。所以後面console.log(foo)時是拿不到bar函數中的局部變量foo = 10,所以只能拿到全局變量foo = 1;因此控制檯輸出1。作用域

上文代碼的另一種形式:
var foo = 1;
    function bar() {
        function foo(){}
        foo = 10;
        return;
    //  function foo() {}    至關於這行代碼提高到最頂部了
    }
    bar();
    console.log(foo);

被搶了風頭的老王果斷的不服氣呀!說我瞎猜扯犢子一廂情願的,本身隨意猜測的。
好的,下面就是開始解釋我爲何說函數function foo(){}提高到最頂端。不改動老王的代碼,讓咱們只是加兩個console.log測試一下相應的輸出結果。io

var foo = 1;
    console.log("全局變量:foo = " + window.foo)
    function bar() {
        console.log("此時bar函數中foo =" + foo)
        foo = 10;
        console.log("bar函數中的變量是" + foo);
        console.log("全局變量foo仍是:"+window.foo);
        return;
        function foo() {}
    }
    bar();
    console.log(foo);
瀏覽器輸出結果

瀏覽器測試結果

經過這裏能夠證明個人猜測是正確的,function foo(){}直接被提高到bar()函數最頂端,而後後面foo = 10就不是再從新定義全局變量了,這裏foo是一個局部變量的角色被定義出現的。所以纔沒有將全局變量給覆蓋,而因爲函數外面是不能直接拿到bar函數當中的局部變量foo,所以繼續向上尋找到全局變量foo = 1.從而輸出1.

我臉都這麼紅了,應該不用打臉了

這裏估計聯想能力豐富的小夥伴確定會舉手說,那麼函數有提高的現象。那麼變量也是否會有提高現象?不錯!不錯!!這位小夥伴聯想的很是正確,學習就要多學會觸類旁通。

獎勵一朵小紅花
【獎勵一朵小紅花】

變量提高
var foo = 1;
    function bar() {
        foo = 10;
        return;
        var foo   //幾乎是相同的代碼,只是把 function foo  變成了   var  foo。變量也是可以提高了的!
    }
    bar();
    console.log(foo);  //仍是輸出1.
思考:

一樣的既然變量可以提高,函數聲明可以提高。那麼誰升的更高呢?

function test(){
        console.log(dabang);
        function dabang(){};
        var dabang;
    }
    test();
    
function test1(){
        console.log(dabang);
        var dabang;
        function dabang(){};
        
    }
    test1();

控制檯輸出結果:

大棒聲明的函數那必須升的高呀!!!
【大棒聲明的函數那必須升的高!!!】

小結:

一、在JavaScript當中,函數做用域當中。變量和聲明函數都可以提高。
二、一樣提高的狀況下,聲明函數提高的更加高!

以上就是鄙人對於JavaScript函數做用域中「提高現象」一點簡單理解,歡迎各位的大佬們指導學習。
ps:打臉也是能夠的,畢竟錯了就是錯了。(那是打臉能否輕一點,留着往後再打呀!(~ ̄▽ ̄)~)

吾雖浪跡天涯,卻從未迷失本心!吾雖惡搞不斷,卻不敢胡亂代碼! 【吾雖浪跡天涯,卻從未迷失本心!吾雖惡搞不斷,卻不敢胡亂代碼!】

相關文章
相關標籤/搜索