1. 程式人生 > 實用技巧 >關於JS型別,那些你不知道的細節

關於JS型別,那些你不知道的細節


最近在重新學習前端,看了課程怕遺忘或者沒有真正明白,在這裡總結一下~(上圖是老師總結的js的結構圖,供參考)

這裡提到的型別都是執行時型別,關於執行時型別,貼一段老師的話

執行時型別是程式碼實際執行過程中我們用到的型別。所有的型別資料都會屬於 7 個型別之一。從變數、引數、返回值到表示式中間結果,任何 JavaScript 程式碼執行過程中產生的資料,都具有執行時型別。

先提出幾個問題

為什麼有的程式設計規範要求用 void 0 代替 undefined?

字串有最大長度嗎?

0.1 + 0.2 不是等於 0.3 麼?為什麼 JavaScript 裡不是這樣的?

ES6 新加入的 Symbol 是個什麼東西?

為什麼給物件新增的方法能用在基本型別上?

7種語言型別

  1. Undefined
  2. Null
  3. Boolean
  4. String
  5. Number
  6. Symbol(ES6)
  7. Object

Undefined和Null

Undefined型別表示未定義,只有一個值undefined,任何變數在宣告之後賦值之前都只有一個型別Undefined,一個值undefined

那麼為什麼要用void 0代替undefined呢?因為undefined在js中不屬於保留字,因此可以作為變數名,這樣undefined就被修改了,而void運算子會使後面的運算結果為undefined,所以可以用void 0代替undefined,防止被修改,還有一個原因,用void 0要比undefined少3個位元組,可以通過列印各自長度來驗證哦。

不過ES5做了修改,undefined只是全域性物件的一個只讀(read-only)屬性,所以在高版本瀏覽器中不會出現undefined被重寫的情況了,但是用void 0代替undefined也不是完全沒必要,很多js壓縮工具正是用的void 0代替undefined。

Null型別也有一個值null,它表示“定義了但是為空”,null是js中的關鍵字。

Boolean

只有兩個值true和false,表示邏輯上的真假。

String

String 有最大長度是 2^53 - 1,這個最大長度並不是字元的長度,因為 String 的意義並非“字串”,而是字串的 UTF16 編碼,我們字串的操作 charAt、charCodeAt、length 等方法針對的都是 UTF16 編碼。所以,字串的最大長度,實際上是受字串的編碼長度影響的。

Number

javaScript 中的 Number 型別有 18437736874454810627(即 264-253+3) 個值

javascript中的Number型別基本符合IEEE中754-2008中規定的雙精度浮點數的規則(根據雙精度浮點數的定義,Number型別中整數的有效範圍是0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 無法精確表示此範圍外的整數),但是JavaScript為了表達幾個額外的場景(比如為了不讓除以0出錯引入無窮大的額概念),規定了幾個裡外情況:

  • NaN:佔用了 9007199254740990,這原本是符合 IEEE 規則的數字;
  • Infinity:無窮大;
  • -Infinity:負無窮大

JS中有+0和-0之分,在除法運算中需要注意區分,看得到的是正無窮大還是負無窮大;

根據浮點數的定義,非整數的Number型別無法用=)來比較,如

console.log(0.1+0.2==0.3)//false

這是浮點數運算的精度問題,在計算時需要先轉換成二進位制再相加,由於一些浮點數在轉換成二進位制是無窮的,而64位雙精度浮點數最大隻能支援53位二進位制,因此被截斷之後再轉成十進位制就會存在一定誤差,但這並不是不可以比較,Number中有一個最小精度值,換句話說就是誤差只要比這個最小精度值小就當這個誤差不存在,因此可以這樣判斷:

console.log(Math.abs(0.1+0.2-0.3) <= Number.EPSILON)//true,

Symbol

建立symbol物件

var obj=Symbol("a");

Object

在js的定義中,物件是“屬性的集合”,屬性分為資料屬性和訪問器屬性,都是key-value解構,key可以是字串或Symbol型別

js中的幾個基本型別,都有一個對應的物件型別

  • Number
  • Boolean
  • String
  • Symbol

所以我們需要認識3和new Number(3)是完全不同的值,一個是Number型別,一個是物件型別

console.log(typeof 3)//number
console.log(typeof (new Number(3)))//object

Number,Boolean,String三個構造器是兩用的,當跟new搭配時,表示建立一個物件,直接呼叫時表示強制型別轉換

Symbol函式比較特殊,不能使用new呼叫,但他依然是Symbol物件的構造器

js語言設計上檢視模糊基本型別和物件的關係,可以把物件的方法在基本型別上使用,如


    console.log("abc".charAt(0)); //a

而在java語言中這是不可以的,而這是因為.提供了裝箱操作,可以基於基本型別構造一個臨時物件。

最後

回答一下開頭的幾個問題

為什麼有的程式設計規範要求用 void 0 代替 undefined?
  因為1.void 0比undefined少3個位元組;2.在低版本瀏覽器中undefined可以作為變數被修改

字串有最大長度嗎?
  有,2^53 - 1

0.1 + 0.2 不是等於 0.3 麼?為什麼 JavaScript 裡不是這樣的?
  浮點數運算規則導致,可以通過Number的最小精度差判斷

ES6 新加入的 Symbol 是個什麼東西?
  Symbol可以生成一個唯一的值,避免key-value結構中的key重複(老師沒有詳細講,自己的理解)

為什麼給物件新增的方法能用在基本型別上?
  js可以進行自動裝箱操作,基於基本型別構建一個臨時物件來呼叫物件方法。

若有錯誤,歡迎留言~