--- title: 'JS 核心 3 - 執行環境、作用域 (下)' tags: JS 核心, Javascript, 執行環境、作用域 description: 2021/02/03 --- JS 核心 -- 執行環境、作用域 (下) === ## Not Defined VS undefined #### undefined : 在記憶體上有準備空間給他,但尚未賦予值 ``` var a; console.log(a); // undefined ``` #### not defined : 在記憶體上沒有準備變數的空間 ``` console.log(a); // a is not defined ``` #### 在開發上要避免將 undefined 的值賦予在變數上 (undefined 是系統自動編配的) #### 若要賦予空植在一個變數上,使用 null ``` var a = null; console.log(a); // null ``` > **「沒有值」與「空值」的差別** **要取一個欄位的值** 如果這個欄位存在,但是沒有輸入任何內容,那就是取到空字串。 如果欄位根本不存在,那就是null。 **空字串(Empty空值): 空的杯子,本來裝水的容器今天沒裝水** null(沒有值): 沒有杯子 ; 一個是連裝水的容器都沒有。 Undefined : 連是不是杯子都不知道。 ## 記憶體存放與釋放 ### 記憶體回收機制 當函式沒有任何物件參考時,就會將記憶體回收。 * 在函式的執行環境中,會創造屬於自己的記憶體空間。 * 當他離開執行環境時,會同時把記憶體空間釋放。 ## 執行緒與同步、非同步 * 單執行緒:一次只能執行一個任務 ( JavaScript 屬於此種 - 針對系統的執行)。 * 多執行緒:可以執行多種任務。 * 同步: 任務依序執行。 * 非同步:setTimeout、event、AJAX 等的這種非同步行為則會先放到事件佇列,等到主要任務都跑完後才會開始執行。(針對程式語言本身) :bulb: **範例 : 請問執行順序** > JavaScript 在執行時,會先以**同步概念**執行主要程式碼,最後才會去執行非同步行為 (非同步行為先移到事件佇列裡 Event queue) ``` function eatBreakfast() { console.log('吃早餐'); } function washingPlate() { console.log('洗餐盤'); } function callSomeone(someone) { console.log('打給' + someone) setTimeout(function () { // 非同步行為先移到事件佇列裡 Event queue console.log(someone + '回電'); }, 0); } function doWork() { var auntie = '漂亮阿姨'; eatBreakfast(); callSomeone(auntie); washingPlate(); } doWork(); // 吃早餐 打給漂亮阿姨 洗碗盤 漂亮阿姨回電 ``` ![](https://i.imgur.com/vKRQiMu.png) :bulb: **範例** > setimeout 會先放到事件佇列裡,等 for 迴圈執行完才執行,所以 i 的最終值是 3。 ``` for(var i=0; i<3; i++) { setTimeout(function(){ console.log(i); // 3 } ,0); } ``` ## :memo: 相關參考文件 :::info [阮一峰電子書](https://es6.ruanyifeng.com/#docs/let) [JavaScript核心篇系列文](https://ithelp.ithome.com.tw/articles/10213660) ::: <style> .red { color: red; } .green { color: green; } </style>