要深刻 JavaScript,你須要掌握這 36 個概念

本文已經原做者受權javascript

clipboard.png

做者:Mahdhi Rezvi 譯者:前端小智 來源:medium前端

原文:https://medium.com/better-pro...java

點贊再看,微信搜索 【大遷世界】 關注這個沒有大廠背景,但有着一股向上積極心態人。本文 GitHub https://github.com/qq44924588... 上已經收錄,文章的已分類,也整理了不少個人文檔,和教程資料。

你可能會常常聽到一些人在抱怨 JS 很奇怪,有時甚至是一文不值。 之因此有這種想法,是由於他們不太瞭解 JS 背後的運做方式。 我也以爲 JS 在某些狀況處理方式與其它語言不太同樣,但這並不能怪它,它也只是以本身的方式展示給你們而已。c++

若是,你熱愛一門編程語言,那麼應該就會想深刻了解並逐個掌握它的概念。git

這裏列出了36個JavaScript概念,你須要掌握這些概念才能成爲一個更懂 JS 的前端開發者。程序員

1.調用堆棧執行

咱們都知道堆棧溢出,可是你知道堆棧溢出是由什麼緣由致使的嗎? 堆棧溢出是與調用堆棧一些操做錯誤相關聯的。github

理解了調用堆棧,你就會清楚解像是JS 這們的編程語言是如何執行的。web

2. 原始數據類型

const foo = "bar";
foo.length; // 3
foo === "bar"; // true

這裏,咱們將值bar分配給常量foo時,它屬於原始類型string。 這個每一個人都知道。 可是各位少俠想沒想過一個問題,string是基本數據類型,怎麼能調用方法了?面試

奇怪嗎? 不。算法

這個特性稱爲自動裝箱。每當讀取一個基本類型的時候,JS 後臺就會建立一個對應的基本包裝類型對象,從而讓咱們可以調用一些方法來操做這些數據。

仍是拿上面的例子開始:

const foo = "bar";
foo.length; // 3
foo === "bar"; // true

變量 foo 是一個基本類型值,它不是對象,它不該該有方法。可是 JS 內部爲咱們完成了一系列處理(即裝箱),使得它可以調用方法,實現的機制以下:

  • 建立String類型的一個實例
  • 在實例上調用指定的方法
  • 銷燬這個實例
const foo  = new String("bar");
foo.length
foo === 'bar'
foo = null

經過對原始數據類型有深刻的瞭解,咱們就應該知道這些「怪異」狀況是如何發生的,以及它們背後的邏輯緣由。

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所作的任何修改也將體如今arr1上。 這是由於它們僅保存值對應的內存地址的引用,而非值自己。

經過了解值類型和引用類型的概念,你就會更好地瞭解如何爲變量分配值和內存引用。

4. 強制類型轉換

這個概念主要解釋了隱式和顯式類型強制之間的區別。 這是前端開發中對 JS 迷惑少數幾個領域之一。 對於隱式強制轉換的概念尤爲如此,由於它對不一樣的數據類型以不一樣的方式表現。

這是 JS 面試中最常被考的。

Number('789')   // 顯式
+'789'          // 隱式
789 != '456'    // 隱式
9 > '5'         // 隱式
10/null          // 隱式
true | 0        // 隱式

掌握了類型顯隱轉換,恭喜你對 JS 瞭解就進一步了。

5. 比較運算符號 和 typeof 運算符

雙等與三等,它們在大多數狀況下在表面上看起來相同而且給出相同的結果,可是,它們有時候可能會給帶來意想不到的錯誤。

爲了瞭解這兩親兄弟的區別,咱們能夠藉助 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 做用域一開始接觸會感到很困惑,可是一旦你瞭解了事情的幕後原理,使用它就會很是使人興奮。

7. 語句和聲明

JavaScript 程序是一系列可執行語句的集合。所謂語句,就是一個可執行的單元,經過該語句的執行,從而實現某種功能。一般一條語句佔一行,並以分號結束。默認狀況下,JavaScript 解釋器按照語句的編寫流程依次執行。若是要改變這種默認執行順序,須要使用判斷、循環等流程控制語句。

咱們應該要知道 語句和聲明 的區別,這對咱們全面瞭解 JS 是頗有幫助的。

8. 當即調用的函數表達式和模塊

IIFE: Immediately Invoked Function Expression,意爲當即調用的函數表達式,也就是說,聲明函數的同時當即調用這個函數。它主要用於避免污染全局做用域。 後來,引入了ES6模塊,爲避免全局做用域的污染提供了一種標準方法,儘管有人認爲它不是IIFE的直接替代。

經過理解IIFE和模塊,你能夠構建較少因爲全局空間處理不當而致使的錯誤的應用程序。固然,使用模塊,咱們還能夠作不少事情。

9.消息隊列和事件循環

正如MDN文檔所說,JavaScript 有一個基於事件循環的併發模型,事件循環負責執行代碼、收集和處理事件以及執行隊列中的子任務。這個模型與其它語言中的模型大相徑庭,好比 C 和 Java。

在併發模型中,消息隊列用於處理最先的消息。 只要有事件發生,便會加入消息隊列中。經過理解這些概念,你能夠更好地理解JS在底層是如何工做的,以及知道你的代碼是若是運行的。

10.時間間隔

想在 JS 有計劃的調用的函數,可使用下面兩個函數:

  • setTimeout 容許咱們在特定時間間隔後運行一次函數。
  • setInterval容許咱們重複運行一個函數,從一個特定的時間間隔開始,而後以該間隔連續重複。

這些與前面的消息隊列和事件處理程序的概念有些關聯。所以,經過理解時間間隔方法,咱們能夠理解它們是如何工做的,並在咱們的用例中有效地使用它們。

11.JS 引擎

JavaScript引擎是執行 JS 代碼的計算機程序或解釋器。JS 引擎能夠用多種語言編寫。例如,驅動Chrome瀏覽器的V8引擎是用 c++ 編寫的,而驅動Firefox瀏覽器的SpiderMonkey引擎是用 C 和 c++編 寫的。

要想編寫高效的代碼,你必須瞭解所使用的 JS 引擎。使用webview的移動開發人員要特別注意這一點。

12.按位運算

按位運算操做將值視爲(0和1),而不是十進制,十六進制或八進制數字。 按位運算符對此類二進制表示形式執行其操做,可是它們返回標準JavaScript數值。

一般,不多會在代碼中使用這些操做,可是它們確實有一些用例。 好比,可使用它們來查找偶數和奇數值,顏色轉換,顏色提取等等。

經過全面瞭解這些按位操做,您能夠很好地使用 WebGL 之類的技術,由於它包含許多像素操做。

13. DOM 和佈局樹

咱們大多數人都據說過文檔對象模型(DOM),但只有少數人對此有深刻的瞭解。 你知道在瀏覽器中看到的不是DOM嗎? 而是渲染樹,它其實是DOM和CSSOM的組合。

經過理解DOM的工做方式、結構以及頁面的渲染方式,咱們就可以在 JS 的幫助下動態地操做web頁面。這對於確保咱們的應用程序具備高標準的性能尤其必要。

14.類和工廠

JavaScript 不是一種面向對象的語言。 可是,爲了模仿OOP屬性,使用了構造函數。 根據Tania的說法,「 JavaScript中的類實際上並無提供其餘功能,只是在原型和繼承上提供語法糖,由於它們提供了更簡潔,更優雅的語法。 因爲其餘編程語言都使用類,所以 JS 中的類語法使開發人員在各類語言之間移動變得更加簡單。」

工廠函數是否是返回對象的類或構造函數的函數。 根據JS專家Eric Elliot的說法,「在JavaScript中,任何函數均可以返回一個新對象。 若是它不是構造函數或類,則稱爲工廠函數。」

當開始開發規模更大的應用程序時,理解這兩個概念是頗有必要的。

15.this 關鍵字和 apply,callbind方法

就我我的而言,我認爲對於一個JS開發人員來講,理解this 關鍵字是相當重要的。若是你不能正確地理解它,未來你開發的項目也會常常遇到this相關的問題。

若是你對this關鍵字很清楚,則能夠看看applycallbind方法,這些均可以解決 this 指向引起的問題。

16.構造函數和 「instanceOf」 運算符

構造函數就像常規函數同樣。 可是它們有不少差別,函數名稱以大寫字母開頭,而且只能由new運算符執行。 具備OOP開發經驗的程序員會熟悉new關鍵字。

爲了正確識別對象的類型,咱們使用instanceOf運算符。 簡單來講,它檢查一個對象是不是另外一個對象的實例。

這才助於你理解對象如何相互繼承,繼承是經過原型實現的。

17.原型

這是 JS 中最使人困惑的概念之一,即便對於有十年經驗的人來講也是如此。

JavaScript中的原型是在對象之間共享通用功能的機制。 JavaScript中幾乎全部對象都是Object的實例。 對象會從Object.prototype繼承全部屬性和方法。

簡單來講,原型是 JS 對象從中繼承方法和屬性的對象。

理解了原型,你就能夠構建高效,快速的應用程序。

18. 使用 newObject.createObject.assign 建立對象

建立對象有不少方法。 可是,大都會選擇Object.create方法而不是new關鍵字。這是有緣由的,由於 使用Object.create方法時,能夠將現有對象用做新建立的對象的原型。 這樣就能夠重用現有對象的屬性和功能,有點像OOP中的繼承概念。

使用Object.assign方法時,能夠將可枚舉的自身屬性從一個或多個源對象複製到目標對象。 在這種狀況下,目標對象的原型不包含源對象的屬性。 這是這兩種方法之間的主要區別。

經過了解對象建立的這三種方式,能夠根據實際狀況適當地使用它們,以建立效率更高的程序。

19.map,filter, reduce 方法

當涉及到數組操做時,這三種方法很是有用。 它們能夠在Array原型中找到。

若是你有一個數組,而且想對每一個元素作一些事情,那麼您可使用map方法。

若是你有一個數組,而且想經過某些條件來過濾一些值時,則可使用filter方法。

reduce() 方法對數組中的每一個元素執行一個由你提供的reducer函數(升序執行),將其結果彙總爲單個返回值。

典型的例子就是對數組的全部元素進行求和:

let numbers = [1,2,3,4,5,6]
const reduced = numbers.reduce( (accumulator, currentValue) => accumulator + currentValue )
console.log(reduced)
// 21

請注意,上述三種方法不會更改原始數組的值。

20.純函數,反作用和狀態變動

這三個概念對於 JS 開發人員而言很是重要,狀態變動對於使用 React 的開發人員尤爲重要。

純函數指的是一個函數的返回結果只依賴於它的參數,而且在執行過程裏面沒有反作用。

函數反作用是指當調用函數時,除了返回函數值以外,還對主調用函數產生附加的影響。反作用的函數不只僅只是返回了一個值,並且還作了其餘的事情,好比:

  • 修改了一個變量
  • 直接修改數據結構
  • 設置一個對象的成員
  • 拋出一個異常或以一個錯誤終止
  • 打印到終端或讀取用戶輸入
  • 讀取或寫入一個文件
  • 在屏幕上畫圖

狀態變動是指你更改變量值的地方。 若是你對變量進行更改,則可能會影響到其餘函數,具體取決於變量被更改以前的值。 在React環境中,建議我不要改變狀態。

21. 閉包

閉包很難理解。 可是一旦理解,你會以爲 JS 其實也挺好的。 在線上有足夠的資源。 你花足夠的時間學習閉包,掌握理解它並不難。

使用閉包能夠訪問內部做用域中外部做用域的做用域。 每次建立函數時都會在函數建立時建立JavaScript閉包。

22. 高階函數

高階函數是將其餘函數做爲參數或返回結果的函數。 你能夠建立僅負責一項任務的較小函數,而後在這些較小函數的幫助下構造複雜函數。 這也會提交代碼的可重用性。

23.遞歸

遞歸是全部編程語言中的一個常見概念。簡單地說,遞歸就是把大問題分解成小問題,而後解決小問題一種思路。

儘管遞歸多是一個讓你頭疼的使人困惑的概念,可是經過大量的練習,從一些小問題開始,你能夠更好地理解它。

24.集合與生成器

ES6 中新引入了集合和生成器。 新引入的集合有MapSetWeakSetWeakMap。 這些集合爲咱們提供一些很方便的操做。 瞭解它們的方式相當重要,尤爲是對於現代JavaScript。

生成器有時很難理解,特別是對於初學者。 生成器容許咱們編寫代碼函數,從而可以暫停和從新啓動函數,而不會阻止其餘代碼的執行,這在JavaScript中是很不常見的。

25. Promise

JecelynPromises 的解釋以下:「想象一下你是個孩子。 你媽媽向你保證,她下週會買一部新手機給你。」

你要到下週才能知道你是否能屋那部手機。你的媽媽要麼真的給你買了一個全新的手機,要麼由於不開心就不給你買。

這算是一個承諾。 一個 Promise 有三個狀態,分別是:

  1. Pending:你不知道你是否會能獲得那個電話
  2. Fulfilled:媽媽高興了,給你買了一部新手機
  3. Rejected:老媽不開心了,就是不給買,愛咋滴就咋滳

26.異步編程

要了解什麼是異步編程,首先要先積善成德什麼是同步編程。 同步編程是線程阻塞的,因爲 JS 是單線程的,所以代碼將逐行執行。

可是使用異步代碼,你能夠執行一些比較耗時的任務。 當你必須執行花費很長時間才能完成的多個任務時,此功能特別有用。 可是在某些狀況下,即便是須要執行很長時間的代碼,也可能須要用同步的方式,這時就可使用async/await

27. ES6 箭頭函數

箭頭函數是 ES6 的新增功能,是常規函數的語法替代。 區別在於箭頭函數不綁定到thisargumentssupernew.target關鍵字。 這使得箭頭函數在某些狀況下是一個不錯的選擇,而在另外一些狀況下則是一個很是糟糕的選擇。

所以,不要一上來就使用箭頭函數。 須要根據你實際狀況還使用它們。

28. 數據結構

不管使用哪一種編程語言,數據結構都是開發人員應具有的基本知識之一。

糟糕的程序員擔憂代碼,好的程序員擔憂數據結構和它們之間的關係。

數據結構方面,你應該瞭解鏈表,隊列,堆棧,樹,圖和哈希表。

29.時間複雜度

無論編程語言如何,時間複雜度分析也是計算機編程的另外一個基礎。 爲了構建更好的應用程序,你應該編寫更好的解決方案。 爲此,你須要瞭解時間複雜度的概念。 有時也稱爲BigO

30.算法

這也是在計算機基礎課程中首先要教的內容之一。 簡而言之,算法是逐步實現目標的過程。 程序員應該可以從算法的角度看任何問題。

儘管有成千上萬個用例的大量算法,可是下面兩個很常見:

  • 查找
  • 排序

這兩個用例對程序員來講是很是常見的,至少應該瞭解實現它們的已知算法。沒有固定的規則規定你應該使用這些算法之一,可是這些算法在性能方面是衆所周知的,而且有很好的文檔證實。

你甚至能夠建立本身的算法,並將其介紹給世界。若是它比目前已知的算法更好,你可能會成爲下一個編程明星

31.繼承,多態和代碼重用

JS 中的繼承可用於原型來實現。 這是由於 JS 是非OOP語言。 可是 JS 經過提供原型繼承來提供OOP的某些功能。

多態是對象、變量或函數能夠採用多種形式的概念。在 JS 中,要看到多態的效果有點困難,由於在靜態類型的系統中,多態的經典類型更明顯。

以上兩個概念均可以幫助咱們在 JS 中實現更好代碼重用。

32.設計模式

設計模式(Design pattern)表明了最佳的實踐,一般被有經驗的面向對象的軟件開發人員所採用。設計模式是軟件開發人員在軟件開發過程當中面臨的通常問題的解決方案。這些解決方案是衆多軟件開發人員通過至關長的一段時間的試驗和錯誤總結出來的。

33. 函數式編程

函數式編程是一種編程範式,是一種構建計算機程序結構和元素的風格,它把計算看做是對數學函數的評估,避免了狀態的變化和數據的可變。

你須要掌握函數式編程的幾個概念:

  • 純函數
  • 不可變
  • 引用透明性
  • 高階函數

34. 簡潔代碼的原則

不管使用哪一種編程語言,這都是每一個開發人員都應該掌握的一項基本技能。 每種編程語言都有一套單獨的良好實踐。 儘管這些「良好」作法是主觀的,而且在工做場所之間存在差別,但有些慣例被認爲是「良好」。

經過遵循這些代碼原則,能夠確保每一個人均可以閱讀和維護你的代碼。 這也會幫助你和你的團隊在應用程序開發過程當中順利合做。

35. 解構賦值

在ES6中引入瞭解構賦值操做符,它很是有用。對於相同的用例,它們比之前的實現更簡單、更有效。

36. ES2020新特性

編程的優勢之一是,若是你不去不斷學習,你永遠不會成爲該領域專家。 編程語言會隨着時間不斷髮展,由於每一個主要版本中都引入了其餘新的功能。

這也說明了你對某個概念的專業知識極可能在未來的10年後會過時,由於會有更好的替代版本與版本更新一塊兒發佈。 對於任何編程語言,這都是很是常見的狀況。

ES202 0發佈了幾個新特性,包括可選連接、空值合併、動態導入等等。你必須學習這些新概念,以跟上快速變化的It世界。

掌握一門語言須要多年的經驗和時間,可是知道要掌握什麼會讓事情變得更容易,但願這 36 個概念能對你有所幫助。

人才們的 【三連】 就是小智不斷分享的最大動力,若是本篇博客有任何錯誤和建議,歡迎人才們留言,最後,謝謝你們的觀看。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

交流

文章每週持續更新,能夠微信搜索 【大遷世界 】 第一時間閱讀,回覆 【福利】 有多份前端視頻等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star。

相關文章
相關標籤/搜索