博文

目前显示的是标签为“Blog”的博文

JavaScript 核心觀念(9)-JS回收機制

图片
 今天要來簡單講一下,關於JS的回收機制究竟是什麼東西 主要的概念會是記憶體的存放與釋放 執行環境中,會創造屬於它的記憶體空間,離開執行環境時,釋放記憶體。 *會在沒有任何物件使用到的時候,回收記憶體。 以下是依些小撇步 需要一直使用 → 放全域變數 函式fn()內需要而已 → 放區域變數 consoel.log也會占用記憶體空間哦 *Chrome小工具 F12開啟開發者工具 → 選擇Memory頁籤 → 按下Take heap snapshot按鈕 可以看網頁佔用了多少記憶體哦。 『如果你能做你擅長的事同時又快樂, 你在生命中以走的比大多數人還遠。』-李奧納多.狄卡皮歐

JavaScript 核心觀念(8)-執行緒與同步、非同步

图片
 嗨,大家好 我是Kris,今天要來分享關於JS的執行緒、事件佇列是如何進行的 那就開始吧~ 單執行緒:一次只能做一件事,做完才會做下一件事,JS就是如此,像是單工的感覺。 多執行緒:可以同時執行多個任務。 同步:依照程式碼依序執行fn() 非同步:針對程式語言本身,放到最後才做。 如同上面範例,doWork()會依序執行三個fn(),且都要等上一個完成才能進行下一個。 非同步:因應JS的某些程式的特性,能達成非同步的樣子。 如同上方範例的setTimeout的用意是隔3秒再執行,JS的處理方式是會先放置事件佇列,讓我們繼續瞭解事件佇列是什麼吧! 事件佇列:非同步行為先移到事件佇列,JS還是依照同步的概念在執行程式碼哦! 依照之前分享過的執行堆疊的概念,會先進入do work()、接著eatBreakfast()完成後離開堆疊,再執行callSomeone() 由於callSomeone內有setTimeout屬於非同步事件,會先放到事件佇列Event Queue,也就是圖片中的右邊方格,等待同步執行結束後再進行。 *注意setTimeout不管秒數設定幾秒都是這樣執行,就算是0秒也是哦* 非同步的例子 addEventListener是屬於監聽事件,那範例寫的意思是當有人點擊時,再去執行clickThis 跟setTimeout一樣是一個非同步事件,會先放到事件佇列等待被點擊的時候才會觸發。 補充 事件佇列有多個非同步事件時 *setTimeout有確定秒數,就可以知道誰先執行 *如果沒有確定,其結果會是隨機的,可以用Promise解決 *AJAX也是非同步事件,需要等待回傳資料 *監聽事件是等使用者觸發才會執行 *非同步的概念是因為JS在執行需要呼叫其他資源時,不能準確知道他的完成時間,所以才會先放到事件佇列。 『用現在的努力,換自己喜歡的人生』

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 額外補充 一.!...

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()尋找也找...

JavaScript 核心觀念(4)-變數作用域(Scope)

图片
嗨,大家好,我是Kris,今天要來講JS的小知識 不同作用域到底差在哪裡?在這一篇裡面跟大家介紹三種不同的作用域。 作用域(Scope) 如同上一篇JS的語法作用域裡面提到的- 連結按這裡 在 JavaScript 中,當一個變數被宣告的時候,它就開始有影響力,而它所影響到的地方,我們就稱之為作用域。 每一個變數都會有自己的作用域,當離開時它就不能作用了,而作用域取決於這個變數產生的地方跟方式。 作用域的等級 JavaScript 中的作用域分為三個等級 Global Level Scope Function Level Scope (Local Scope) Block Level Scope (ES6) Global Level Scope 全域作用域 在每個 JavaScript 環境中,都一定會有一個全域物件(全域環境),在 HTML 中我們稱之為 window。 在全域環境宣告的變數就稱之為全域變數,而它能影響的地方就是全域作用域。 全域變數的影響範圍非常廣大,不論是函式(function)內外,他的影響力遍布整個程式碼。 Function Level Scope (Local Scope)  區域作用域 在函式內被宣告的變數就稱為區域變數,所影響的地方就是區域作用域,也就是函式的大括號內,一旦離開 function 使用的話,就會出現 ReferenceError:xxx is not defined 未定義的錯誤訊息。 *在函式內,若變數沒有被宣告,就會被自動轉為全域變數 如上圖,b 在函式內沒有被宣告,所以變成全域變數,所以外面的 console.log 讀得到,而宣告過的 a 作用域只在test函式內作用 *如果在函式內外有相同的變數名稱,並且想要在函式內取得此變數的值,會優先使用區域變數的值,除非使用 window 才能去取得全域變數的值 Block Level Scope (ES6)  區塊作用域 是比區域更小的範圍,影響力只有變數被宣告的大括號和子區塊。 其實 function scope(區域作用域) 也可以被視為一種區塊作用域,在ES6之前的版本是不支持此區塊作用域的 在以前的版本使用var宣告變數時,是沒有區塊作用域的。 在 ES6 後才出現的 let、const ,就是支持區塊作用域,準確來說是他們只支持區...

JavaScript 核心觀念(2)-執行的錯誤情境 (RHS, LHS)

哈囉大家好,我是Kris 今天要來介紹在JS裡面比較常見的錯誤 RHS、LHS跟取值以及賦予值有很大的關係 以下來分別跟大家解釋⬇️ RHS(Right-hand side) RHS取值來自右側的變數上 像是 console.log(ming);     //ming有定義過(var ming ='小名') 紅色這行就是從右側的變數ming取值來讓console.log可以印出變數的值 console.log(min);   //min沒有定義過 錯誤訊息:ReferenceError : min is not defined. 這個錯誤訊息就是在說min是沒有定義過的變數,因此沒有辦法取到他的值,導致錯誤。 RHS不會在編譯過程中直接出現錯誤,要在執行階段才會看到錯誤 也就是網頁上按F12後看到的console才能看到這段錯誤訊息。 LHS(left-hand side) 用來賦予值到左側變數上 我們定義變數時就是LHS哦 像是var ming = '小名'; 要把'小名'這個值給ming 就是LHS 所以今天左側的值沒有辦法被賦予的時候就會出現錯誤訊息啦 ex:'小明' =1; 錯誤訊息:Invalid left-hand side in assighment. 意思就是左側值無法被賦予,'小明'不是一個變數沒有辦法被賦予值。 LHS屬於編譯過程中所發生的錯誤,編譯的結果不會出現。 在開發環境就會看到錯誤訊息,網頁上看不到執行後的結果。 RHS也可以用在其他地方,並不是只有在函式取值的時候。 ex:var man = ming; 用RHS取得右側變數ming的值; 用LHS賦予值到左邊變數man; 這邊再分享一個常見的錯誤訊息 Error:Line3:Unexpected end of input. 就是在說Line3第三行結尾的部分有錯誤,可能是少了括號或是最重要的結尾分號';' 在JS遇到這些錯誤呢,一定要進行修正!! 如果沒有修正的話,後面的程式碼都不會運行,會停在有錯誤的那一行! 所以遇到這些錯誤的時候,記得要修正哦! 今天這一篇主要是可以更認識JS的錯誤訊息 在遇到的時候才不會很慌張很苦惱,很有可能只是一些小地方沒注意到,修正過來就好囉。 『把前進的動力從因...

JavaScript 核心觀念(1)-JavaScript是如何運行的呢? (直譯語言、編譯語言的差異)

图片
哈囉大家好,我是Kris 今天要來分享課程中的第一堂課-JavaScript如何運行以及直譯語言與編譯語言的差異在哪裡 因為電腦無法直接看懂原始碼,也就是我們工程師所撰寫出來的程式碼 所以會經過一些處理來讓電腦瞭解以後再去運行。 直譯語言和編譯語言的差異 直譯語言:執行前未經編譯,像是JavaScript就是直譯語言哦。 好處:彈性比較高、不需要預先定義型別。 *錯誤會直接反映在環境中,ex:chrome裡的console 編譯語言:會預先編譯再運行。 好處:預先編譯就可以預先除錯、語言效能比較好。 *大多時候我們在說某種語言為編譯或直譯語言時,指的是【 大多數 】並非全部。 就像是我們說JavaScript是直譯語言,不代表JavaScript不能有編譯器,反之亦然。 JavaScript直譯器轉換過程 語法基本單元化(Tokenizing):將JS裡的標點符號、詞彙先分別解析出來。    *JS=JavaScript 抽象結構樹AST(Abstract Syntax Tree):將整個原始碼的結構定義出來。 代碼生成: 最後一步才會生成代碼。 生成出來的代碼會根據環境的不同稍微有不一樣的地方。 *在結構樹的階段尚未運行程式碼 可以利用這個網站來更深入的瞭解整個轉換過程👇 https://esprima.org/demo/parse.html# 接下來操作並解釋給大家看 首先在左側輸入程式碼 var 變數 = '內容'; 這邊我輸入的是【var ming = '小名';】 右側的頁籤選到Tokens,可以看到拆成了各個不同的標點符號以及詞彙。 Keyword是關鍵字,內容(value)為"var";Punctuator是標點符號。 有點像小時候寫作文時,需要先瞭解各個詞語的意思以及不同的標點符號代表什麼意思, Tokenizing就是在做這樣子的事情,先拆開分類但還不會瞭解我們是在定義一個變數。 點選最左側:結構樹Tree 轉換成電腦看得懂的方式,Tree有點像是JSON格式。 VariableDeclarator: 定義一個變數 kind:定義變數的方法是 var Identifier: 變數的字詞;name:內容是ming 然後把'小名'這個詞彙賦予進變數。 到這裡才會知道我們正在定義一個變...

開始自我學習的第一步-撰寫部落格Blog

嗨,大家好嗎? 我是Kris,一個佔世界比例70%的生產者,卻是世界少數的四分人。 好~回歸正題哈哈哈,人類圖有機會再跟大家分享心得。 工作了兩三年卻始終找不到工作的意義 似乎只是為了賺錢而工作(? 於是我決定停下腳步,好好感受、好好思考自己的未來方向。 待業的日子裡,身為拖延症患者的我,總是腦袋想很多,實際作為卻不多 但在經歷了面試不順利以後,好好的正視自己能力不足。 決定找線上課程! 我購買的是六角學院-JavaScript核心篇 感受跟以前上巨X那種差很多哈哈,但因為才剛開始上課所以就暫時先不評論。 上課的過程裡都會在這裡更新文章,跟大家分享心得~ 開始自我學習的第一步-撰寫部落格Blog 寫部落格有什麼好處呢? 讓履歷更豐富、加分 擁有個人品牌、網站,在面試時履歷更加分,可以讓面試官更清楚了解你學習過什麼,以及你自我研究、自我學習的能力高,而不是空口說白話而已。   替自己整理技術脈絡、進行自我學習後的復習 網路上的文章、課程看再多遍,如果沒有真正吸收就不是自己的東西。 透過撰寫文章的方式,同時也是再次幫自己整理觀念,深度學習。 增加網路聲量  假設有一天辭了工作後,你除了公司的職稱以外還剩下什麼標籤?建立網路上的聲量,讓自己擁有其他標籤。 透過撰寫部落格的方式,幫助自己學習,也記錄了成長的過程,就像是作品集能夠給面試官參考,增加自己的價值,提高面試錄取率。   我還是新手,應該沒辦法寫文章教別人吧? 只要你開始做,不管分享什麼都一定有人比你晚開始會需要你的分享。每個人的背景都不盡相同,也許就是有人跟你背景很像,也跟你一樣想學習同個東西。 更資深的人寫的文章,可能會因為習慣所以有許多專業的術語導致新手看不懂,對於剛入門的人能看懂文章是很重要的事,因此你的分享對他來說就會有很大幫助。 這世界上,永遠都有比你菜的人需要你的資源分享。   該寫什麼才好呢?感覺網路上都有人寫過了 只要是你覺得重要的、怕會忘記就可以寫文章記錄下來 語法、指令或是看了其他網站後也可以寫自己理解過後的解釋 研究過後寫範例程式碼codepen,也可以幫助自己更深入學習。 生活想分享的事情也可以寫,用標籤tag分類即可,不需要侷限自己只能限定寫某個主題。(標籤tag可以讓Google搜尋用關鍵字找到就是所謂的SEO搜尋引擎最佳化,想辦法讓網站在googl...