博文

目前显示的是 三月, 2023的博文

JavaScript 核心觀念(7)-執行環境與作用域-提升Hoisting

图片
嗨,大家好嗎? 我是Kris 今天要來分享一個我個人認為很有趣的觀念 以下截至  MDN  說明 提升(Hoisting)是在 ECMAScript® 2015 Language Specification 裡面找不到的專有名詞。它是一種釐清 JaveScript 在執行階段內文如何運行的思路(尤其是在創建和執行階段)。然而,提升一詞可能會引起誤解:例如,提升看起來是單純地將變數和函式宣告,移動到程式的區塊頂端,然而並非如此。變數和函數的宣告會在編譯階段就被放入記憶體,但實際位置和程式碼中完全一樣。 所以提升只是一個用來釐清JS如何運行的觀念,瞭解JS創造階段、執行階段做了什麼 對程式碼的結果又有什麼影響呢? 首先 JS在函式、變數宣告時,會先建立一個記憶體空間來存放他們的key&value,如下圖 var   a  =  '1'; 在創造階段時建立a的儲存空間,但尚未賦予值,在執行階段時才會賦予值 所以可以將它看作這樣  ↓ //創造階段 var a; //執行階段 a = '1'; 函式陳述式在創造階段就會優先載入,並且將整個函式內容一起寫入 我們直接來看一個範例碼 * 函式比變數有更高的優先權 ,所以會比變數更優先被建立 * 所以,答案如下 console.log(myName);   //小明 在創造階段時,myName尚未被賦予值,在那個時候會儲存的值為undefined。 是因為JS必須告訴我們它已準備好記憶體空間,若沒有給值會出現Error。 因此! 上面的範例程式碼,並不會進入if條件式! If裡的 myName 在創造階段時值為 undefined,故判斷式不會執行 後面 myName 又被賦予“小明”,所以myName 的值會印出小明 *if(myName)  是在判斷myName是否為 falsy值,是的話不會執行,否的話才執行 myName是falsy值,所以不會進入if(myName)的判斷式裡。 *常見 falsy值有 false、null、undefined、NaN、 0、 -0、""、'' *參考範例: https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy 額外補充 一.!是一個NOT語句,會將結果反轉

JavaScript 核心觀念(6)-執行環境與作用域-範圍鍊

图片
嗨~大家好,我是Kris 今天要來說明 為什麼明明宣告在外層的變數甚至是不同地方的函式,卻可以正確的呼叫與執行。 範圍鍊 函式裡面沒有需要的變數時,就會向外層尋找 變數在外層宣告,但內層卻可以取得 JavaScript是語法作用域,所以並不會與執行堆疊有任何關係。 因此fu1()不會因為他是在fu2()下被呼叫 就去尋找fu2()裡的var value = 2;     而是會去外層尋找外面的var value =1;。 範圍鍊真正的意思是「當函式本身沒有相對應的變數或函式時,就會向外層去尋找」 而這個尋找的過程就是【範圍鍊】,因此這邊與執行堆疊、執行環境不會有任何直接關係。 JavaScript 因為是語法作用域的關係,在程式碼撰寫完畢時,就已經決定了作 用域。 以下提供幾個範例,大家可以跟著做做看哦 不同情況下分別會列印出什麼呢? 答案放在最下方 1. 2. 3. 4. 5. 解答分隔線 ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.  哈囉~老媽 2.  哈囉~老媽 3.  哈囉~漂亮阿姨 4.  哈囉~老爸 5.  哈囉~老媽 //1. 只執行sayHi(),sayHi()裡沒有person此變數,因此向外層尋找,找到全域變數的'老媽' 其他兩個fn裡的變數皆是區域變數,不影響sayHi() //2. doMorningWork()裡的變數為區域變數,不影響sayHi(); *函式沒有被呼叫就不會執行哦,所以meetAuntie()不會執行 //3. 執行meetAuntie()時內部有person,故印出'漂亮阿姨' 不被doMorningWork()的'老爸'影響 //4. 執行meetAuntie()時內部沒有person變數,所以向外層doMorningWork()尋找所以印出'老爸' //5. 執行meetAuntie()時內部沒有person變數,所以向外層doMorningWork()尋找也找不到時 就會再