#JavaScript

前言

如果要舉出一個在 JavaScript 裡面很重要也很常用,但新手常常搞混的概念,那「非同步(Asynchronous)」當仁不讓,絕對是第一名。跟其他那些 thisclosureprototype 或是 hoisting 比起來,非同步在實際開發的時候用到的頻率高太多了,而且是初學者常常會踩坑的地方。

非同步真的那麼難嗎?

我相信不是的。只要循著一個正確的脈絡前進,就可以循序漸進理解為什麼需要非同步,也能知道在 JavaScript 裡面是怎麼處理這種操作的。

類似的主題我其實在四年前就寫過,但現在回頭看實在是寫得滿差的,所以四年後重新挑戰這個主題,希望能寫出一篇品質不錯的文章,把非同步這件事情講清楚。

在寫這篇文章之前,參考了 Node.js 的官方文件,發現在非同步的講解上其實做得不錯,因此本文會以類似的切入點開始談這個問題。如果不會 Node.js 也沒關係,我底下會稍微做點介紹。

建議閱讀本文以前需要具備 JavaScript 基礎,知道如何使用 JavaScript 操作 DOM,也知道什麼是 ajax。

接著就讓我們開始吧!

閱讀更多

前言

在 JavaScript 裡面,有一個令新手十分頭痛,老手也不一定能完全理解的主題:「this 是什麼?」。身為一個以 JavaScript 當作吃飯工具的前端工程師,我也被這個問題困擾了許久。

我原本以為我這輩子都不會寫有關於 this 的文章。

原因有兩個,第一個是講解 this 的文章已經超級無敵多了,而且每一篇都寫得很不錯,之前看完 What’s THIS in JavaScript ? 系列之後覺得講解的很完整,若是沒有把握自己能夠講得更清楚或是以不同的角度切入,似乎就沒必要再寫一篇文章;第二個原因是若是想要「完全」搞懂 this,要付出的成本可能比你想像中要大得多。

閱讀更多

前言

請先原諒我用了一個比較聳動的標題,因為實在是想不到還有什麼標題好下,最後選擇了一個可能比較有爭議的標題,但能利用這樣的標題激起討論也是滿有趣的,何況我說這話也是有根據的。

在觀看此篇文章之前請先看過上一篇:我知道你懂 hoisting,可是你了解到多深?,因為文章內容有部分相關,所以必須先有 Execution Context 以及 Variable Object 的觀念以後,才能夠吸收這篇文章的東西。

如果你只對文章標題的那句:「所有的函式都是閉包」有興趣,那可以直接往下拉,因為要講閉包就必須先從作用域開始講起,所以這篇文章按照慣例不會太短,前面也會有一定程度的鋪陳。

好,讓我們從作用域開始吧。

閱讀更多

前言

2021-06-09 補充:

感謝讀者 blackr1234 留言,此文章為 2018 年 11 月發表,底下程式碼輸出結果大概是以 Node.js v8.17.0 為準,因此對於一些狀況的輸出可能會跟現在不太一樣。例如說存取宣告前的 let 變數,當初的結果為:ReferenceError: a is not defined,現在用 Node.js v14 的結果則是:ReferenceError: Cannot access 'a' before initialization

這陣子我在忙一些教學相關的東西,稍微準備一些資料之後教了學生們 JavaScript 裡面的 hoisting,也就是「提升」這個觀念,例如說以下程式碼:

console.log(a)
var a = 10

會輸出undefined而不是ReferenceError: a is not defined,這種現象就叫做 Hoisting,變數的宣告被「提升」到最上面去了。

如果你只想了解最基本的 hoisting,其實差不多就是這樣,但後來我還教了letconst相關的一些知識,不過前一天剛教學完,隔天就立刻看到相關的技術文章還發現自己教錯,因此特別花了一點時間打算好好理解 hoisting 這個東西。

很多東西沒有深入研究的時候你都會覺得沒什麼,真的跳下去深入去看才會發現自己其實還有一大堆概念沒有搞懂。

有很多人都知道 hoisting,但是理解程度卻不盡相同,我列出了 10 個項目,如果有任何一點你剛好不知道的話,那恭喜,這篇文章應該可以為你帶來一些收穫。

  1. 你知道什麼是 hoisting
  2. 你知道 hoisting 只會提升宣告而非賦值
  3. 你知道 function 宣告、function 的參數以及一般變數宣告同時出現時的提升優先順序
  4. 你知道 let 跟 const 沒有 hoisting
  5. 你知道第四點是錯的,其實有但只是表現形式不一樣
  6. 你知道有關第五點,有個概念叫做 TDZ(Temporal Dead Zone)
  7. 你看過 ES3 的規格書,知道裡面是怎麼描述的
  8. 你看過 ES6 的規格書,知道裡面是怎麼描述的
  9. 你知道 hoisting 背後的原理是什麼
  10. 你看過 V8 編譯出來的程式碼

你可能會問說:「我為什麼要知道的這麼深?有什麼用?」,其實我也覺得對 hoisting,只要知道基本的就行了。只要你有好好地宣告變數,就算不知道那些,對日常生活或是工作也不會有太大的影響。

可是假如你像我一樣,想要有朝一日在自己的履歷上面放上「精通 JavaScript」的話,那對這些東西就不能逃避。同時你如果對底層的這些細節愈熟悉,會碰到的問題就愈少,也愈能理解為什麼會有 hoisting 的出現,當你想要在技術這條路上走得更遠爬得更高時,我覺得這些細節是很重要的。

接下來,我們就一步步來看 hoisting 吧!

閱讀更多

前言

其實這週原本是要來寫淺拷貝跟深拷貝的差異以及實作,但在找資料的時候無意間又看到 call by value 與 call by reference 相關的文章,越研究發現越有趣。原本以為自己已經搞懂了這個問題,但沒想到看的資料越多,卻把自己弄的越糊塗。

要寫這篇文章其實有兩個不同的方式,一個是詳實記錄我研究這個問題的過程以及心中的疑惑,以及最後如何得到解答,簡單來說就是按照時間軸來寫;另外一個是當我研究完以後,再重新以自己的方式整理,並且用更簡單易懂的方式來表達。

以往我的文章大多數都走第二種路線,重新歸納整理過後再寫出一篇相對上更容易理解的文章,用我的方式帶著大家一步步跟著我的脈絡去探討問題最後得出解答。

但這次我想嘗試第一種,帶大家看看我平常寫文章的時候都看了哪些資料,以及發想的過程為何,這樣應該也滿有趣的。

Let’s go!

閱讀更多

前言

一般來說在學習寫網頁的時候,最先碰到的會是 HTML 與 CSS,負責把版面刻出來以及美化版面,當基礎打穩之後,會開始學習 JavaScript,試著做出一點互動性的效果。而「互動」除了使用者跟瀏覽器的互動以外,別忘了還有 Client 端跟 Server 端的互動,也就是必須要學會從瀏覽器用 JavaScript 跟後端 Server 拿資料,否則你的網頁資料都只能是寫死的。

這篇的主要預設讀者是網頁前端的初學者,希望能讓本來不太理解怎麼跟 Server 交換資料或是怎麼串 APi 的讀者看完之後,能夠更了解該怎麼跟後端串接。

閱讀更多

前言

老實說 JavaScript 的原型鍊一直是我很懼怕的一個主題,理由很簡單,因為真的不太好理解。光是一堆名詞跟錯綜複雜的關係就可以把你搞瘋,例如說prototype, __proto__, constructor, Object.prototype, Function.prototype, new等等。

可是呢,這又確實是 JavaScript 很重要的一部分,而且是面試的必考題,就算現在不懂,以後遲早有一天要把它弄懂,不然的話永遠都沒辦法把自己的技術能力往上提高一個檔次。

有關原型鍊的文章你可以在網路上搜到一大堆,每一篇的理解方式都不太一樣,有些直接搬出一大堆專有名詞,嚇都把你嚇死了。而我也是一直到最近,看了幾篇我覺得切入角度比較不錯的文章,才真正對原型鍊有比較深刻的理解。

就趁著現在這個機會,讓我們多瞭解一點 JavaScript 的原型鍊吧!這篇適合對 JavaScript 有一點概念但又不是很清楚的人觀看,如果文章中有講錯的地方,也麻煩不吝在評論中指出,感謝。

閱讀更多

前言

最近剛好上到 CS50 Week3,這一週的主題是:Algorithms,裡面介紹到了幾種經典的排序法,像是選擇排序、泡沫排序、插入排序以及合併排序。

我覺得身為一個軟體工程師,大概一輩子都脫離不了排序了,畢竟這是經典演算法之一嘛!與其每次要面試之前都凌亂的準備,不如現在就整理出一篇,紀錄一下各個排序法的心得,幫自己做個統整。

因此,這一篇將利用 JavaScript 來實作各個經典排序演算法。

這次實做的排序法都會是由小到大排序,並且為了方便起見,每一個排序法「都會直接更改原本的 array」,但如果你不想改到原本的也很簡單,在每一個的函式最開頭加上:arr = arr.slice()複製一份原本的即可。

還有,因為文章裡面比較難放動畫,所以我只能放一些圖片而已,若是想搭配視覺化演算法一起學習的話,我非常推薦 VISUALGO,這網站絕對會讓你對排序的理解度更上一層樓。

閱讀更多

之前寫了一篇文章簡單的筆記一下自己在看redux的心得,在這邊還是要再次推薦官方文件,因為寫的超級清楚。

但是之前在看官方文件的時候,middleware的地方沒有完全看懂,看到後面就霧煞煞了
這次重看了一遍官方文件講middleware跟非同步操作的地方,邊看邊做筆記,總算是把middleware的實作原理弄懂了
依照慣例分享一下心得
官方文件(中譯版,但是還沒翻譯到這篇)

官方文件很棒的點就是這篇不只教你怎麼用,還從頭講起,讓你知道為什麼middleware會是現在這樣的形式。

閱讀更多

在Javascript裡面,有一個超級重要的概念就是非同步,這也是剛入門的時候最容易搞混、忘記的觀念
ES6原生支援了Promise,搭配Generator使用效果更佳,而ES7甚至支援了async的語法
我覺得這算是一個演進的過程,讓程式架構越來越好、可讀性越來越高
所以要講解這些新的東西,就先從最基本的callback開始吧

閱讀更多