標籤:代碼塊 class 引擎 str 開頭 代碼 div 指派陳述式 技術分享
首先看一段JS代碼,其中使用了兩種方式聲明了兩個函數,分別在不同的地方調用兩個函數:
1 <script> 2 ‘use strict‘; 3 // 輸出hello函數 4 console.log(hello); 5 // 定義hello函數 6 function hello(){ 7 alert("Hello"); 8 } 9 // 輸出hi變數10 console.log(hi);11 // 給hi賦一個函數12 var hi = function(){13 alert("Hi");14 }15 // 輸出變數hi16 console.log(hi);17 </script>在JS中,定義函數有兩種方式,分別是“函數語句”和“運算式”。 - 針對hello函數,我在還沒有定義它之前就調用了它,並且我定義hello函數使用的“函數語句”定義的方式。 - 針對hi函數,我使用的是“運算式”的定義方式,也在定義之前和之後調用了該函數。結果如下所示:我們可以看到,使用“函數語句”的方式定義的函數可以“先使用,後定義”。而使用“運算式”定義的函數只能“先定義,後使用”。 為什麼會出現這種情況呢,我談談我個人的理解,如果有不對的地方,希望可以幫我糾正一下:
我們都知道JS預設有一個全域對象window,在運行一段JS代碼時:
第一步:JS引擎會先掃描整個JS代碼,把所有全域變數都綁定到window對象上,包括hello和hi這兩個變數。此時,window上就有了hello函數(包括函數體)和hi變數(但值為undefined)。
第二步:開始從第一行執行JS代碼,這時雖然還沒有執行到hello函數的定義語句,但是window中已經有了函數定義了。而沒有執行到hi變數的指派陳述式之前,hi變數用於是undefined。
綜上所述:導致了兩種函數定義方式導致的“定義”和“使用”的順序不同。 為了驗證猜想,我們在JS代碼塊的開頭添加兩行console:
1 console.log(window.hello);2 console.log(window.hi);
輸出結果如下:
這其中也牽涉到了“變數提升”的概念,其實都可以用綁定到window對象上來理解:在執行JS代碼之前,所有的全域變數(包括函數和變數),都會綁定到window對象上,只是函數會包含函數體,變數僅僅是一個undefined。
我只是個新手,如果有理解上的偏差還望指出,萬分感謝!
簡單說明一下JS中的函式宣告存在的“先使用,後定義”