 作者 | 小鹿 來源 | 小鹿動畫學編程
寫在前邊第一次去面試,面試官問我0.1 + 0,2 __ 0.3?估計很多人都知道在 JS 中0.1 + 0.2 != 0.3 的,至于大于還是小于還真沒弄明白。 像這種變態(tài)的問題,在 JS 中存在很多,那小鹿就干脆整理成了一系列,希望對你的 JS 基礎進一步加牢,也希望你能在面試中順利拿到 offer。 1、學習困惑 我先談談我自己之前在方面遇到的困惑,學習 JS 很多基礎的知識起初不是那么順利的,尤其是剛接觸 JS 的時候,因為 JS 歷史遺留了一些 bug,再加上它是弱類型語言,不像其它面向對象強類型語言很多概念一樣清晰。 2、學習建議 不建議在剛接觸就深入學習,很多知識知道這么回事就可以,比如null為什么通過 typeof 檢測為對象類型,一開始你只知道他通過 typeof 檢測為對象類型就可以。什么時候去理解這些知識點的原理? 如果你覺得自己很懶,那就先不要去學習了,如果你對它的原理感興趣,自然而然你就學會探索了。但是,到了面試的時候,當面試官問到你這塊問題的時候,會遞歸式的問你了,到時候,你不得不去學原理了,這是你會發(fā)現(xiàn),這些原理性的東西零散,這個人說東,那個人說西,然后我就根據(jù)優(yōu)質的文章自己學習了下,整理成了一系列。
思維導圖
一、基本類型的分類JS 的基本類型分為兩大類型,分別為原始類型和對象類型。 原始類型包括哪些?對象類型包括哪些?為什么要這樣分類?他們的區(qū)別又是什么? 原始類型存儲的都是值,而對象類型存儲的都是地址。如下圖:

 如上圖所示,我們清楚了原始類型和對象類型最根本的區(qū)別,那么問題又來了,當我們進行變量之間賦值的時候,原始類型直接賦值的是值,而對象類型賦值的是地址。 
 所以,當我們將對象作為參數(shù)進行傳遞的時候,在函數(shù)內改變的是該地址指向的對象,而傳遞的參數(shù)是原始類型,則改變的是一個副本(復制的另一個值)。也就是說,如果是對象,則改變了原始的值,而不能改變原始類型原始的值。
原始類型共六種,分別為String 、Number 、Boolean 、nul l、undefined 、symbol 。 接下來對這六種原始類型中存在的問題我們逐一解決。
二、null對于null有一個歷史存留的 bug,null是對象類型嗎?雖然我們使用 typeof 檢測null是對象類型,這其實是一個 bug。 2.1 原因是什么? 因為 JS 最初的版本是 32 位系統(tǒng)的,為了將性能將用低位存儲變量類型信息,000 開頭表示代表的是對象,此時null表示全零,所以系統(tǒng)就錯誤的將null判斷為對象類型。雖然 JS 內部判斷代碼已經更改,但是這個 bug 一直留存下來。 2.2 null 出現(xiàn)的情況匯總 1、手動設置變量的值或者對象某一個屬性值為null(此時不賦值,后邊會賦值)。 2、在 JS 的 DOM 元素獲取中,如果沒有獲取到指定的元素對象,結果一般都是null。 3、Object.prototype._proto_的值也是null。 4、正則捕獲的時候,如果沒有獲取到結果,默認的也是null。
三、symbol有關symbol使用的比較少,但是它的存在是有原因的。 3.1 symbol 是什么? symbol表示獨一無二的值,因為由于對象的屬性都是字符串類型,我們避免不了相同字符串沖突的問題。所以為了防止對象的屬性都是字符串類型而沖突引入的。 3.2 symbol 的使用 // 通常參數(shù)是字符串類型,如果為對象類型,就會調用 toString 方法
let s1 = Symbol(參數(shù));// 這個參數(shù)可以認為是 Symbol 實例的一個描述,用于區(qū)分
// 第一種寫法
let a = {};
a[s1] = 'Hello!';
// 第二種寫法
let a = {
[s1] = 'Hello';
}
四、undefined4.1 undefined 出現(xiàn)的情況? 1、變量提升: 只聲明未定義默認值就是undefined。 2、嚴格模式下:沒有明確的執(zhí)行主體,this就是undefined。 3、對象沒有這個屬性名,屬性值是undefined。 4、函數(shù)定義形參不傳值,默認就是undefined。 5、函數(shù)沒有返回值(沒有return或者return;),默認返回的就是 undefined。
五、為什么 0.1 + 0.2 != 0.3 ?上邊我們講了一些有關數(shù)據(jù)類型的坑,我們回過頭來,0.1 + 0.2 __ 0.3呢?為什么會出現(xiàn)不相等的情況呢?面試該如何回答面試官? 5.1 是什么導致了這種情況? 原因很簡單,JS 采用的是雙精度版本,這個版本就存在精度問題,就導致了上邊這種情況。 5.2 內部的原理是什么? 我們計算機的信息全部轉化為二進制進行存儲的,那么0.1的二進制表示的是一個無限循環(huán)小數(shù),該版本的 JS 采用的是浮點數(shù)標準需要對這種無限循環(huán)的二進制進行截取,從而導致了精度丟失,造成了0.1不再是0.1,截取之后0.1變成了 0.100…001,0.2變成了0.200…002。所以兩者相加的數(shù)大于0.3。 那好,既然0.1不等于0.1了,那為什么我在控制臺上輸出console.log(0.1)還等于0.1呢? 因為在輸入內容進行轉換的時候,二進制轉換成十進制,然后十進制轉換成字符串,在這個轉換的過程中發(fā)生了取近似值,所以打印出來的是一個近似值。 如果你把上邊的原理和面試官一說,臥槽,面試官不給你 offer 都難,哈哈,開個玩笑,拿到 offer 不僅靠基礎,也要靠你的其他綜合能力。
六、小結今天我們主要總結了一下有關 JS 基礎的知識點,雖然這些知識點比較坑,也比較雜,但是通過整理清晰了很多,文章中可能講的地方有問題,可以給小鹿指出。 這些不但是基礎,更是面試中最高頻面試官常常問到了,不同的公司面試官的問法也是大不相同,所以換湯不換藥,上邊總結的知識點也存在很多不足的地方,歡迎各位大佬補充。
作者Info: 【作者】:小鹿 【原創(chuàng)公眾號】:小鹿動畫學編程。 【簡介】:和小鹿同學一起用動畫的方式從零基礎學編程,將 Web前端領域、數(shù)據(jù)結構與算法、網(wǎng)絡原理等通俗易懂的呈獻給小伙伴。先定個小目標,原創(chuàng) 1000 篇的動畫技術文章,和各位小伙伴共同努力一起學習!
|