重學前端——JS基礎

1.JavaScript規定了幾種語言類型?

  • Number
  • String
  • Boolean
  • undefined
  • Null
  • Object
  • Symbol
  • Set
  • Map
  • BigInt(一種內置對象,它提供了一種方法來表示大於 2^53 - 1 的整數。這本來是 Javascript中能夠用 Number 表示的最大數字。BigInt 能夠表示任意大的整數)

2.JavaScript對象的底層數據結構是什麼,在內存中的具體存儲形式?

  • JavaScript基本類型數據都是直接按值存儲在棧中的(Undefined、Null、不是new出來的布爾、數字和字符串),每種類型的數據佔用的內存空間的大小是肯定的,並由系統自動分配和自動釋放。這樣帶來的好處就是,內存能夠及時獲得回收,相對於堆來講 ,更加容易管理內存空間。javascript

  • JavaScript引用類型數據被存儲於堆中 (如對象、數組、函數等,它們是經過拷貝和new出來的)。其實,說存儲於堆中,也不太準確,由於,引用類型的數據的地址指針是存儲於棧中的,當咱們想要訪問引用類型的值的時候,須要先從棧中得到對象的地址指針,而後,在經過地址指針找到堆中的所須要的數據。java

3.Symbol類型在實際開發中的應用、可手動實現一個簡單的Symbol。

Symbol表示獨一無二的值(須要注意的是經過 Symbol()方法建立值的時候不能使用 new 操做符,緣由是經過 new 實例化的結果是一個 object 對象,而不是原始類型的 symbol)數組

  • 實際開發中,當遇到比較複雜的對象或是須要多人共同維護的對象類型數據,容易產生屬性名的重複,使用symbol能夠避免這樣的問題:
const opt1 = Symbol('key');
const opt2 = Symbol('key');
const obj = {
    [opt1]: 'value',
    [opt2]: 'value',
}
// obj:{Symbol(key): "value", Symbol(key): "value"}
複製代碼
  • 第二種狀況是模擬類中的私有變量
// a.js

const privateKey = Symbol('key')
class myClass{
    constructor(){
        this.name = 'test'
        // 由於Symbol獨一無二的特性,此處的屬性只能在a.js中被訪問,
        // 新建出來的實例也沒法訪問該屬性,本質上是沒法訪問privateKey。
        this[privateKey] = 'strange' 
    }
}

複製代碼

4.基本類型對應的內置對象,以及他們之間的裝箱拆箱操做?

如 String、Number、Boolean、Object、Function、Array、Date、RegExp、Error。實際上這些是一些內置函數,這些內置函數能夠當作構造函數來使用,從而建立一個對應子類型的新對象。安全

  • 所謂的裝箱,是指將基本數據類型轉換爲對應的引用類型的操做。而裝箱又分爲隱式裝箱和顯式裝箱。
  • 拆箱就和裝箱相反。是指把引用類型轉換成基本的數據類型。一般經過引用類型的valueOf()和toString()方法來實現。

具體不展開,詳見 juejin.cn/post/684490…markdown

5.null和undefined的區別

  • undefined的字面意思是:未定義的值。在試圖讀取未定義或者定義了未賦值的變量時會返回。數據結構

  • null的字面意思是:空值。在內存中能夠表示爲棧中的指針地址沒有指向堆中的內存對象。(在JS最初的實現中,中的值是由一個表示類型的標籤和實際數據值表示的,對象的類型標籤是0。因爲null表明的是空指針0x00,所以,null的類型標籤也成爲了 0,typeof null就錯誤的返回了"object")函數

6.至少能夠說出三種判斷JavaScript數據類型的方式,以及他們的優缺點,如何準確的判斷數組類型?

  1. typeof
  • 優勢:書寫簡單,易於理解
  • 缺點:只能區分基本數據類型,沒法判斷複雜數據類型,如null,Array,Date等(function有效)
  1. instanceof
  • 優勢:能夠判斷一個實例是不是其父類型或者祖先類型的實例
  • 缺點:左側必須爲對象(沒法判斷null,undefined),當原型鏈發生變更時會判斷錯誤
  1. Object.prototype.toString.call
  • 優勢:能夠直接輸出數據類型字符串,易於判斷,適用全部數據類型
  • 缺點:書寫麻煩

判斷數組:Object.prototype.toString.call(new Array()) === '[object Array]'post

7.出現小數精度丟失的緣由,JavaScript能夠存儲的最大數字、最大安全數字,JavaScript處理大數字的方法、避免精度丟失的方法?

緣由:JS 遵循 IEEE 754 規範,採用雙精度存儲(double precision),佔用 64 bit。1位用來表示符號位,11位用來表示指數,52位表示尾數。ui

由於在計算機最底層,數值的運算和操做都是採用二進制實現的,因此計算機沒有辦法精確表示浮點數,而只能用二進制近似相等的去表示浮點數的小數部分。this

0.1 >> 0.0001 1001 1001 1001…(1001無限循環)
0.2 >> 0.0011 0011 0011 0011…(0011無限循環)

0.1+0.2 = 0.01001100110011001100110011001100110011001100110011001110
轉十進制0.30000000000000004
複製代碼

當進行計算或其餘操做時時,四捨五入(逢1進,逢0舍)將會致使最終的運算結果存在誤差。

而大整數也存在一樣的問題,由於表示尾數的尾數只有52位,所以 JS 中能精準表示的最大整數是 Math.pow(2, 53),即十進制9007199254740992。(ES2015的BigInt就是用來解決大數問題)

能夠引入Math.js等一些專門處理此問題的三方庫來解決精度丟失。

相關文章
相關標籤/搜索