JS裡一切都是物件嗎?!
不知道之前在哪看的一句話:"在JS裡,一切都是物件~",當時覺得還挺有道理的.畢竟像常用的函式,陣列等的確都是物件!(可以用typeof檢視).
補充一句: typeof null // "object" 因為這個是js一開始的bug
來談談關於 typeof 的原理吧,我們可以先想一個很有意思的問題,js 在底層是怎麼儲存資料的型別資訊呢?或者說,一個 js 的變數,在它的底層實現中,它的型別資訊是怎麼實現的呢?
其實,js 在底層儲存變數的時候,會在變數的機器碼的低位1-3位儲存其型別資訊
000:物件
010:浮點數
100:字串
110:布林
1:整數
but, 對於 undefined 和 null 來說,這兩個值的資訊儲存是有點特殊的。
null:所有機器碼均為0
undefined:用 −2^30 整數來表示
所以,typeof 在判斷 null 的時候就出現問題了,由於 null 的所有機器碼均為0,因此直接被當做了物件來看待。
真的全是物件嗎?
var a = '' b = 1 c = new String('1') d = new Number(1) typeof a // 'string' typeof b // 'number' typeof c // 'object' typeof d // 'object'
為什麼會出現這種差異呢?
因為js裡有6中基本型別:
1.undefined // typeof undefined'undefined'
2. null // typeof null 'object'
3. string //
4. number //
5. Boolean // typeof true 'boolean'
6. Symbol
當我們以字面量的方式建立string, number時,創建出來的屬於基本型別,而通過構造器創造出來時它是一個物件!
但是!~ 竟然字面量創造出來的玩意兒不是物件,它為什麼會有方法和屬性!!
var a = 'a' a.toString() // 'a' a.length // 1
按道理說屬性和方法應該是物件特有的呀!
於是乎,引出了JS的另一個概念, 裝箱和拆箱!
JS裡的裝箱和拆箱
概念:
1.裝箱指的是,將一個值變成指向該值的物件。(複製值)
2.拆箱指的是,把指向值的物件還原成該值。(複製值)
裝箱
var a = 'str' a.toString() 當執行toString()方法時,JS會自動將其包裝成String物件再呼叫方法.過程如下: { // 虛擬碼 var b = new String(a) b.toString() b = null } 然後我們就看到了正常的輸出'a'
這個也可以解釋另外一個問題:
var a='str' a.name='test' console.log(a.name) // undefined
聰明的你一定可以想到這是為什麼了!
拆箱
var a = new String('str') console.log(a) // String {"str"} var b = a + '1' console.log(b) // str1
這裡就是一個拆箱的過程,JS做的事情和上面裝箱類似.
var b = a + '1' { var temp = a.toString() // or valueOf or var b = temp + '1' }
型別轉換時會經常發生裝箱和拆箱操作,需要注意