你可能會經常聽到一些人在抱怨 JS
很奇怪,有時甚至是一文不值。之所以有這種想法,是因為他們不太了解 JS
背后的運作方式。我也覺得 JS
在某些情況處理方式與其它語言不太一樣,但這并不能怪它,它也只是以自己的方式展現(xiàn)給大家而已。
如果,你熱愛一門編程語言,那么應該就會想深入了解并逐個掌握它的概念。
這里列出了36個JavaScript
概念,你需要掌握這些概念才能成為一個更懂 JS
的前端開發(fā)者。
1.調用堆棧執(zhí)行
我們都知道堆棧溢出,但是你知道堆棧溢出是由什么原因導致的嗎? 堆棧溢出是與調用堆棧一些操作錯誤相關聯(lián)的。
理解了調用堆棧,你就會清楚解像是JS 這們的編程語言是如何執(zhí)行的。
2. 原始數據類型
const foo = "bar";
foo.length; // 3
foo === "bar"; // true
這里,我們將值bar分配給常量foo
時,它屬于原始類型string
。這個每個人都知道。但是各位少俠想沒想過一個問題,string
是基本數據類型,怎么能調用方法了?
奇怪嗎? 不。
這個特性稱為自動裝箱
。每當讀取一個基本類型的時候,JS 后臺就會創(chuàng)建一個對應的基本包裝類型對象
,從而讓我們能夠調用一些方法來操作這些數據。
還是拿上面的例子開始:
const foo = "bar";
foo.length; // 3
foo === "bar"; // true
變量 foo 是一個基本類型值,它不是對象,它不應該有方法。但是 JS 內部為我們完成了一系列處理(即裝箱),使得它能夠調用方法,實現(xiàn)的機制如下:
- 創(chuàng)建String類型的一個實例
- 在實例上調用指定的方法
- 銷毀這個實例
const foo = new String("bar");
foo.length
foo === 'bar'
foo = null
通過對原始數據類型有深入的了解,我們就應該知道這些“怪異”情況是如何發(fā)生的,以及它們背后的邏輯原因。
3.值類型和引用類型
最近,我對 "引用傳遞" 在 JS
是怎么工作的感到困惑。盡管我知道 C
和 Java
等語言中有“按引用傳遞”和“按值傳遞”的概念,但是我不確定它在 JS
中如何工作。
你是否知道分配給 JS
中非原始值的變量對該值的引用?引用指向存儲值的內存位置。。
var arr1 = [1,2,3];
var arr2 = arr1;
arr2.push(10);
console.log(arr2);
//[1, 2, 3, 10]
console.log(arr1);
//[1, 2, 3, 10]
上面的示例中可以看到,對arr2
所做的任何修改也將體現(xiàn)在arr1
上。這是因為它們僅保存值對應的內存地址的引用,而非值本身。
通過了解值類型和引用類型的概念,你就會更好地了解如何為變量分配值和內存引用。
4. 強制類型轉換
這個概念主要解釋了隱式和顯式類型強制之間的區(qū)別。這是前端開發(fā)中對 JS
迷惑少數幾個領域之一。對于隱式強制轉換
的概念尤其如此,因為它對不同的數據類型以不同的方式表現(xiàn)。
這是 JS
面試中最常被考的。
Number('789') // 顯式
+'789' // 隱式
789 != '456' // 隱式
9 > '5' // 隱式
10/null // 隱式
true | 0 // 隱式
掌握了類型顯隱轉換,恭喜你對 JS
了解就進一步了。
5. 比較運算符號 和 typeof 運算符
雙等與三等,它們在大多數情況下在表面上看起來相同并且給出相同的結果,但是,它們有時候可能會給帶來意想不到的錯誤。
為了了解這兩親兄弟的區(qū)別,我們可以借助 typeof
來查看被比較的值的類型。
typeof 3 // "number"
typeof "abc" // "string"
typeof {} // "object"
typeof true // "boolean"
typeof undefined // "undefined"
typeof function(){} // "function"
typeof [] // "object"
typeof null // "object"
6. JavaScript 作用域
作用域是 JS
中一個很重要的尷尬,JS
也一直在不斷完善自己的作用域。根據Wissam的說法,作用域的簡單定義是,編譯器在需要時查找變量和函數。
了解作用域有助于我們有效地使用JavaScript
。我們還需要了解全局作用域
以及塊和函數作用域,也稱為詞法作用域。JS
作用域一開始接觸會感到很困惑,但是一旦你了解了事情的幕后原理,使用它就會非常令人興奮。
(推薦教程: JavaScript教程)
7. 語句和聲明
JavaScript
程序是一系列可執(zhí)行語句的集合。所謂語句,就是一個可執(zhí)行的單元,通過該語句的執(zhí)行,從而實現(xiàn)某種功能。通常一條語句占一行,并以分號結束。默認情況下,JavaScript
解釋器按照語句的編寫流程依次執(zhí)行。如果要改變這種默認執(zhí)行順序,需要使用判斷、循環(huán)等流程控制語句。
我們應該要知道 語句和聲明 的區(qū)別,這對我們全面了解 JS 是很有幫助的。
8. 立即調用的函數表達式和模塊
IIFE: Immediately Invoked Function Expression
,意為立即調用的函數表達式,也就是說,聲明函數的同時立即調用這個函數。它主要用于避免污染全局作用域。后來,引入了ES6
模塊,為避免全局作用域的污染提供了一種標準方法,盡管有人認為它不是IIFE
的直接替代。
通過理解IIFE
和模塊,你可以構建較少由于全局空間處理不當而導致的錯誤的應用程序。當然,使用模塊,我們還可以做很多事情。
9.消息隊列和事件循環(huán)
正如MDN
文檔所說,JavaScript
有一個基于事件循環(huán)的并發(fā)模型,事件循環(huán)負責執(zhí)行代碼、收集和處理事件以及執(zhí)行隊列中的子任務。這個模型與其它語言中的模型截然不同,比如 C
和 Java
。
在并發(fā)模型中,消息隊列用于處理最早的消息。只要有事件發(fā)生,便會加入消息隊列中。通過理解這些概念,你可以更好地理解JS
在底層是如何工作的,以及知道你的代碼是如果運行的。
10.時間間隔
想在 JS
有計劃的調用的函數,可以使用下面兩個函數:
setTimeout
允許我們在特定時間間隔后運行一次函數。setInterval
允許我們重復運行一個函數,從一個特定的時間間隔開始,然后以該間隔連續(xù)重復。 這些與前面的消息隊列和事件處理程序的概念有些關聯(lián)。因此,通過理解時間間隔方法,我們可以理解它們是如何工作的,并在我們的用例中有效地使用它們。
11.JS 引擎
JavaScript
引擎是執(zhí)行 JS
代碼的計算機程序或解釋器。JS
引擎可以用多種語言編寫。例如,驅動Chrome
瀏覽器的V8引擎是用 c++
編寫的,而驅動Firefox
瀏覽器的SpiderMonkey
引擎是用 C
和 c++
編寫的。
要想編寫高效的代碼,你必須了解所使用的 JS
引擎。使用webview
的移動開發(fā)人員要特別注意這一點。
12.按位運算
按位運算操作將值視為位(0和1),而不是十進制,十六進制或八進制數字。按位運算符對此類二進制表示形式執(zhí)行其操作,但是它們返回標準JavaScript數值。
通常,很少會在代碼中使用這些操作,但是它們確實有一些用例。比如,可以使用它們來查找偶數和奇數值,顏色轉換,顏色提取等等。
通過全面了解這些按位操作,您可以很好地使用 WebGL
之類的技術,因為它包含許多像素操作。
13. DOM 和布局樹
我們大多數人都聽說過文檔對象模型(DOM),但只有少數人對此有深入的了解。你知道在瀏覽器中看到的不是DOM
嗎?而是渲染樹,它實際上是DOM
和CSSOM
的組合。
通過理解DOM
的工作方式、結構以及頁面的渲染方式,我們就能夠在 JS
的幫助下動態(tài)地操作web頁面。這對于確保我們的應用程序具有高標準的性能尤為必要。
14.類和工廠
JavaScript
不是一種面向對象的語言。但是,為了模仿OOP
屬性,使用了構造函數。根據Tania
的說法,“JavaScript
中的類實際上并沒有提供其他功能,只是在原型和繼承上提供語法糖,因為它們提供了更簡潔,更優(yōu)雅的語法。由于其他編程語言都使用類,因此 JS
中的類語法使開發(fā)人員在各種語言之間移動變得更加簡單。”
工廠函數是不是返回對象的類或構造函數的函數。根據JS
專家Eric Elliot
的說法,“在JavaScript
中,任何函數都可以返回一個新對象。如果它不是構造函數或類,則稱為工廠函數?!?/p>
當開始開發(fā)規(guī)模更大的應用程序時,理解這兩個概念是很有必要的。
15.this 關鍵字和 apply,call及bind方法
就我個人而言,我認為對于一個JS開發(fā)人員來說,理解this
關鍵字是至關重要的。如果你不能正確地理解它,將來你開發(fā)的項目也會經常遇到this
相關的問題。
如果你對this
關鍵字很清楚,則可以看看apply
,call
和bind
方法,這些都可以解決 this
指向引發(fā)的問題。
16.構造函數和 “instanceOf” 運算符
構造函數就像常規(guī)函數一樣。但是它們有很多差異,函數名稱以大寫字母開頭,并且只能由new
運算符執(zhí)行。具有OOP
開發(fā)經驗的程序員會熟悉new
關鍵字。
為了正確識別對象的類型,我們使用instanceOf
運算符。簡單來說,它檢查一個對象是否是另一個對象的實例。
這才助于你理解對象如何相互繼承,繼承是通過原型實現(xiàn)的。
17.原型
這是 JS
中最令人困惑的概念之一,即使對于有十年經驗的人來說也是如此。
JavaScript
中的原型是在對象之間共享通用功能的機制。JavaScript
中幾乎所有對象都是Object
的實例。對象會從Object.prototype
繼承所有屬性和方法。
簡單來說,原型是 JS
對象從中繼承方法和屬性的對象。
理解了原型,你就可以構建高效,快速的應用程序。
(推薦微課:JavaScript微課)
18. 使用 new,Object.create 和 Object.assign 創(chuàng)建對象
創(chuàng)建對象有很多方法。但是,大都會選擇Object.create
方法而不是new
關鍵字。這是有原因的,因為 使用Object.create
方法時,可以將現(xiàn)有對象用作新創(chuàng)建的對象的原型。這樣就可以重用現(xiàn)有對象的屬性和功能,有點像OOP
中的繼承概念。
使用Object.assign
方法時,可以將可枚舉的自身屬性從一個或多個源對象復制到目標對象。在這種情況下,目標對象的原型不包含源對象的屬性。這是這兩種方法之間的主要區(qū)別。
通過了解對象創(chuàng)建的這三種方式,可以根據實際情況適當地使用它們,以創(chuàng)建效率更高的程序。
19.map,filter, reduce 方法
當涉及到數組操作時,這三種方法非常有用。它們可以在Array
原型中找到。
如果你有一個數組,并且想對每個元素做一些事情,那么您可以使用map
方法。
如果你有一個數組,并且想通過某些條件來過濾一些值時,則可以使用filter
方法。
reduce()
方法對數組中的每個元素執(zhí)行一個由你提供的reducer
函數(升序執(zhí)行),將其結果匯總為單個返回值。
典型的例子就是對數組的所有元素進行求和:
let numbers = [1,2,3,4,5,6]
const reduced = numbers.reduce( (accumulator, currentValue) => accumulator + currentValue )
console.log(reduced)
// 21
請注意,上述三種方法不會更改原始數組的值。
20.純函數,副作用和狀態(tài)變更
這三個概念對于 JS
開發(fā)人員而言非常重要,狀態(tài)變更對于使用 React
的開發(fā)人員尤其重要。
純函數指的是一個函數的返回結果只依賴于它的參數,并且在執(zhí)行過程里面沒有副作用。
函數副作用是指當調用函數時,除了返回函數值之外,還對主調用函數產生附加的影響。副作用的函數不僅僅只是返回了一個值,而且還做了其他的事情,比如:
- 修改了一個變量
- 直接修改數據結構
- 設置一個對象的成員
- 拋出一個異?;蛞砸粋€錯誤終止
- 打印到終端或讀取用戶輸入
- 讀取或寫入一個文件
- 在屏幕上畫圖
狀態(tài)變更是指你更改變量值的地方。如果你對變量進行更改,則可能會影響到其他函數,具體取決于變量被更改之前的值。在React環(huán)境中,建議我不要改變狀態(tài)。
21. 閉包
閉包很難理解。但是一旦理解,你會覺得 JS
其實也挺好的。在線上有足夠的資源。你花足夠的時間學習閉包,掌握理解它并不難。
使用閉包可以訪問內部作用域中外部作用域的作用域。每次創(chuàng)建函數時都會在函數創(chuàng)建時創(chuàng)建JavaScript
閉包。
22. 高階函數
高階函數是將其他函數作為參數或返回結果的函數。你可以創(chuàng)建僅負責一項任務的較小函數,然后在這些較小函數的幫助下構造復雜函數。這也會提交代碼的可重用性。
23.遞歸
遞歸是所有編程語言中的一個常見概念。簡單地說,遞歸就是把大問題分解成小問題,然后解決小問題一種思路。
盡管遞歸可能是一個讓你頭疼的令人困惑的概念,但是通過大量的練習,從一些小問題開始,你可以更好地理解它。
24.集合與生成器
ES6
中新引入了集合和生成器。新引入的集合有Map
,Set
,WeakSet和WeakMap
。這些集合為我們提供一些很方便的操作。了解它們的方式至關重要,尤其是對于現(xiàn)代JavaScript
。
生成器有時很難理解,特別是對于初學者。生成器允許我們編寫代碼函數,從而能夠暫停和重新啟動函數,而不會阻止其他代碼的執(zhí)行,這在JavaScript
中是很不常見的。
25. Promise
Jecelyn
對 Promises
的解釋如下:“想象一下你是個孩子。你媽媽向你保證,她下周會買一部新手機給你?!?/p>
你要到下周才能知道你是否能屋那部手機。你的媽媽要么真的給你買了一個全新的手機,要么因為不開心就不給你買。
這算是一個承諾。一個 Promise
有三個狀態(tài),分別是:
Pending
:你不知道你是否會能得到那個電話Fulfilled
:媽媽高興了,給你買了一部新手機Rejected
:老媽不開心了,就是不給買,愛咋滴就咋滳
26.異步編程
要了解什么是異步編程,首先要先積善成德什么是同步編程。同步編程是線程阻塞的,由于 JS
是單線程的,因此代碼將逐行執(zhí)行。
但是使用異步代碼,你可以執(zhí)行一些比較耗時的任務。當你必須執(zhí)行花費很長時間才能完成的多個任務時,此功能特別有用。但是在某些情況下,即使是需要執(zhí)行很長時間的代碼,也可能需要用同步的方式,這時就可以使用async/await
。
27. ES6 箭頭函數
箭頭函數是 ES6
的新增功能,是常規(guī)函數的語法替代。區(qū)別在于箭頭函數不綁定到this
,arguments
,super
或new.target
關鍵字。這使得箭頭函數在某些情況下是一個不錯的選擇,而在另一些情況下則是一個非常糟糕的選擇。
因此,不要一上來就使用箭頭函數。需要根據你實際情況還使用它們。
28. 數據結構
無論使用哪種編程語言,數據結構都是開發(fā)人員應具備的基本知識之一。
糟糕的程序員擔心代碼,好的程序員擔心數據結構和它們之間的關系。
數據結構方面,你應該了解鏈表,隊列,堆棧,樹,圖和哈希表。
29.時間復雜度
不管編程語言如何,時間復雜度分析也是計算機編程的另一個基礎。為了構建更好的應用程序,你應該編寫更好的解決方案。為此,你需要了解時間復雜度的概念。有時也稱為BigO
。
30.算法
這也是在計算機基礎課程中首先要教的內容之一。簡而言之,算法是逐步實現(xiàn)目標的過程。程序員應該能夠從算法的角度看任何問題。
盡管有成千上萬個用例的大量算法,但是下面兩個很常見:
- 查找
- 排序
這兩個用例對程序員來說是非常常見的,至少應該了解實現(xiàn)它們的已知算法。沒有固定的規(guī)則規(guī)定你應該使用這些算法之一,但是這些算法在性能方面是眾所周知的,并且有很好的文檔證明。
你甚至可以創(chuàng)建自己的算法,并將其介紹給世界。如果它比目前已知的算法更好,你可能會成為下一個編程明星。
31.繼承,多態(tài)和代碼重用
JS
中的繼承可用于原型來實現(xiàn)。這是因為 JS
是非OOP
語言。但是 JS
通過提供原型繼承來提供OOP
的某些功能。
多態(tài)是對象、變量或函數可以采用多種形式的概念。在 JS
中,要看到多態(tài)的效果有點困難,因為在靜態(tài)類型的系統(tǒng)中,多態(tài)的經典類型更明顯。
以上兩個概念都可以幫助我們在 JS
中實現(xiàn)更好代碼重用。
32.設計模式
設計模式(Design pattern
)代表了最佳的實踐,通常被有經驗的面向對象的軟件開發(fā)人員所采用。設計模式是軟件開發(fā)人員在軟件開發(fā)過程中面臨的一般問題的解決方案。這些解決方案是眾多軟件開發(fā)人員經過相當長的一段時間的試驗和錯誤總結出來的。
33. 函數式編程
函數式編程是一種編程范式,是一種構建計算機程序結構和元素的風格,它把計算看作是對數學函數的評估,避免了狀態(tài)的變化和數據的可變。
你需要掌握函數式編程的幾個概念:
- 純函數
- 不可變
- 引用透明性
- 高階函數
34. 簡潔代碼的原則
無論使用哪種編程語言,這都是每個開發(fā)人員都應該掌握的一項基本技能。每種編程語言都有一套單獨的良好實踐。盡管這些“良好”做法是主觀的,并且在工作場所之間存在差異,但有些慣例被認為是“良好”。
通過遵循這些代碼原則,可以確保每個人都可以閱讀和維護你的代碼。這也會幫助你和你的團隊在應用程序開發(fā)過程中順利合作。
35. 解構賦值
在ES6
中引入了解構賦值操作符,它非常有用。對于相同的用例,它們比以前的實現(xiàn)更簡單、更有效。
36. ES2020新特性
編程的優(yōu)點之一是,如果你不去不斷學習,你永遠不會成為該領域專家。編程語言會隨著時間不斷發(fā)展,因為每個主要版本中都引入了其他新的功能。
這也說明了你對某個概念的專業(yè)知識很可能在將來的10年后會過期,因為會有更好的替代版本與版本更新一起發(fā)布。對于任何編程語言,這都是非常常見的情況。
ES2020
發(fā)布了幾個新特性,包括可選鏈接、空值合并、動態(tài)導入等等。你必須學習這些新概念,以跟上快速變化的It世界。
掌握一門語言需要多年的經驗和時間,但是知道要掌握什么會讓事情變得更容易,希望這36個概念能對你有所幫助。
文章來源:medium.com/better-programming/36-javascript-concepts-you-need-to-master-to-become-an-expert-c6630ac41bf4