動畫:面試官問我 0.1 + 0.2 __ 0.3 ? 爲什麼?該如何正確回答?

在這裏插入圖片描述
作者 | 小鹿
來源 | 小鹿動畫學編程


寫在前邊

第一次去面試,面試官問我0.1 + 0,2 __ 0.3?估計很多人都知道在 JS 中0.1 + 0.2 != 0.3 的,至於大於還是小於還真沒弄明白。

像這種變態的問題,在 JS 中存在很多,那小鹿就乾脆整理成了一系列,希望對你的 JS 基礎進一步加牢,也希望你能在面試中順利拿到 offer。

1、學習困惑

我先談談我自己之前在方面遇到的困惑,學習 JS 很多基礎的知識起初不是那麼順利的,尤其是剛接觸 JS 的時候,因爲 JS 歷史遺留了一些 bug,再加上它是弱類型語言,不像其它面向對象強類型語言很多概念一樣清晰。

2、學習建議

不建議在剛接觸就深入學習,很多知識知道這麼回事就可以,比如null爲什麼通過 typeof 檢測爲對象類型,一開始你只知道他通過 typeof 檢測爲對象類型就可以。什麼時候去理解這些知識點的原理?

如果你覺得自己很懶,那就先不要去學習了,如果你對它的原理感興趣,自然而然你就學會探索了。但是,到了面試的時候,當面試官問到你這塊問題的時候,會遞歸式的問你了,到時候,你不得不去學原理了,這是你會發現,這些原理性的東西零散,這個人說東,那個人說西,然後我就根據優質的文章自己學習了下,整理成了一系列。


思維導圖

在這裏插入圖片描述

一、基本類型的分類

JS 的基本類型分爲兩大類型,分別爲原始類型和對象類型。

原始類型包括哪些?對象類型包括哪些?爲什麼要這樣分類?他們的區別又是什麼?

原始類型存儲的都是值,而對象類型存儲的都是地址。如下圖:
在這裏插入圖片描述
在這裏插入圖片描述
如上圖所示,我們清楚了原始類型和對象類型最根本的區別,那麼問題又來了,當我們進行變量之間賦值的時候,原始類型直接賦值的是值,而對象類型賦值的是地址。

在這裏插入圖片描述
在這裏插入圖片描述
所以,當我們將對象作爲參數進行傳遞的時候,在函數內改變的是該地址指向的對象,而傳遞的參數是原始類型,則改變的是一個副本(複製的另一個值)。也就是說,如果是對象,則改變了原始的值,而不能改變原始類型原始的值。

原始類型共六種,分別爲StringNumberBooleannull、undefinedsymbol

接下來對這六種原始類型中存在的問題我們逐一解決。


二、null

對於null有一個歷史存留的 bug,null是對象類型嗎?雖然我們使用 typeof 檢測null是對象類型,這其實是一個 bug。

2.1 原因是什麼?

因爲 JS 最初的版本是 32 位系統的,爲了將性能將用低位存儲變量類型信息,000 開頭表示代表的是對象,此時null表示全零,所以系統就錯誤的將null判斷爲對象類型。雖然 JS 內部判斷代碼已經更改,但是這個 bug 一直留存下來。

2.2 null 出現的情況彙總

1、手動設置變量的值或者對象某一個屬性值爲null(此時不賦值,後邊會賦值)。

2、在 JS 的 DOM 元素獲取中,如果沒有獲取到指定的元素對象,結果一般都是null。

3、Object.prototype._proto_的值也是null。

4、正則捕獲的時候,如果沒有獲取到結果,默認的也是null。


三、symbol

有關symbol使用的比較少,但是它的存在是有原因的。

3.1 symbol 是什麼?

symbol表示獨一無二的值,因爲由於對象的屬性都是字符串類型,我們避免不了相同字符串衝突的問題。所以爲了防止對象的屬性都是字符串類型而衝突引入的。

3.2 symbol 的使用

 // 通常參數是字符串類型,如果爲對象類型,就會調用 toString 方法
 let s1 = Symbol(參數);// 這個參數可以認爲是 Symbol 實例的一個描述,用於區分
 
 // 第一種寫法
 let a = {};
 a[s1] = 'Hello!';
 
 // 第二種寫法
 let a = {
    [s1] = 'Hello';
}

四、undefined

4.1 undefined 出現的情況?

1、變量提升: 只聲明未定義默認值就是undefined。

2、嚴格模式下:沒有明確的執行主體,this就是undefined。

3、對象沒有這個屬性名,屬性值是undefined。

4、函數定義形參不傳值,默認就是undefined。

5、函數沒有返回值(沒有return或者return;),默認返回的就是 undefined。


五、爲什麼 0.1 + 0.2 != 0.3 ?

上邊我們講了一些有關數據類型的坑,我們回過頭來,0.1 + 0.2 __ 0.3呢?爲什麼會出現不相等的情況呢?面試該如何回答面試官?

5.1 是什麼導致了這種情況?

原因很簡單,JS 採用的是雙精度版本,這個版本就存在精度問題,就導致了上邊這種情況。

5.2 內部的原理是什麼?

我們計算機的信息全部轉化爲二進制進行存儲的,那麼0.1的二進制表示的是一個無限循環小數,該版本的 JS 採用的是浮點數標準需要對這種無限循環的二進制進行截取,從而導致了精度丟失,造成了0.1不再是0.1,截取之後0.1變成了 0.100…001,0.2變成了0.200…002。所以兩者相加的數大於0.3。

那好,既然0.1不等於0.1了,那爲什麼我在控制檯上輸出console.log(0.1)還等於0.1呢?

因爲在輸入內容進行轉換的時候,二進制轉換成十進制,然後十進制轉換成字符串,在這個轉換的過程中發生了取近似值,所以打印出來的是一個近似值。

如果你把上邊的原理和麪試官一說,臥槽,面試官不給你 offer 都難,哈哈,開個玩笑,拿到 offer 不僅靠基礎,也要靠你的其他綜合能力。


六、小結

今天我們主要總結了一下有關 JS 基礎的知識點,雖然這些知識點比較坑,也比較雜,但是通過整理清晰了很多,文章中可能講的地方有問題,可以給小鹿指出。

這些不但是基礎,更是面試中最高頻面試官常常問到了,不同的公司面試官的問法也是大不相同,所以換湯不換藥,上邊總結的知識點也存在很多不足的地方,歡迎各位大佬補充。


推薦閱讀

1、動畫:面試如何輕鬆手寫鏈表?
2、動畫:如何給面試官寫一個滿意的冒泡排序
3、別再翻了,面試二叉樹看這 11 個就夠了~
4、動畫:動畫從零學編程之 “棧” 你掌握這些必備了嗎?


❤️ 不要忘記留下你學習的腳印 [點贊 + 收藏 + 評論]

文章都看完了,爲何不妨點個贊呢?嘻嘻,那就說明你很自私,你怕那麼好的文章讓別人也看到。開個小小玩笑。

其實我也很自私,我把我的一直以來堅持原創的公衆號:「小鹿動畫學編程」偷偷給你,裏邊匯聚了小鹿以動畫形式講解的數據結構與算法、網絡原理、Web 等技術文章。
在這裏插入圖片描述

動一動你的小手,點贊就完事了,每個人出一份力量(點贊 + 評論)就會讓更多的學習者加入進來!非常感謝! ̄ω ̄=


作者Info:

【作者】:小鹿

【原創公衆號】:小鹿動畫學編程。

【簡介】:和小鹿同學一起用動畫的方式從零基礎學編程,將 Web前端領域、數據結構與算法、網絡原理等通俗易懂的呈獻給小夥伴。先定個小目標,原創 1000 篇的動畫技術文章,和各位小夥伴共同努力一起學習!公衆號回覆 “資料” 送一從零自學資料大禮包!

【轉載說明】:轉載請說明出處,謝謝合作!~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章