不知道之前在哪看的一句話:"在JS里,一切都是對象~",當時覺得還挺有道理的.畢竟像常用的函數(shù),數(shù)組等的確都是對象!(可以用typeof查看).
補充一句: typeof null // "object"
因為這個是js一開始的bug
來談?wù)勱P(guān)于 typeof 的原理吧,我們可以先想一個很有意思的問題心包,js 在底層是怎么存儲數(shù)據(jù)的類型信息呢类咧?或者說,一個 js 的變量蟹腾,在它的底層實現(xiàn)中痕惋,它的類型信息是怎么實現(xiàn)的呢?
其實娃殖,js 在底層存儲變量的時候值戳,會在變量的機器碼的低位1-3位存儲其類型信息
000:對象
010:浮點數(shù)
100:字符串
110:布爾
1:整數(shù)
but, 對于 undefined 和 null 來說,這兩個值的信息存儲是有點特殊的炉爆。
null:所有機器碼均為0
undefined:用 ?2^30 整數(shù)來表示
所以堕虹,typeof 在判斷 null 的時候就出現(xiàn)問題了卧晓,由于 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'
為什么會出現(xiàn)這種差異呢?
因為js里有6中基本類型:
1.undefined // typeof undefined 'undefined'
2. null // typeof null 'object'
3. string //
4. number //
5. Boolean // typeof true 'boolean'
6. Symbol
當我們以字面量的方式創(chuàng)建string, number時,創(chuàng)建出來的屬于基本類型,而通過構(gòu)造器創(chuàng)造出來時它是一個對象!
但是!~ 竟然字面量創(chuàng)造出來的玩意兒不是對象,它為什么會有方法和屬性!!
var a = 'a'
a.toString() // 'a'
a.length // 1
按道理說屬性和方法應(yīng)該是對象特有的呀!
于是乎,引出了JS的另一個概念, 裝箱和拆箱!
JS里的裝箱和拆箱
概念:
1.裝箱指的是逼裆,將一個值變成指向該值的對象。(復(fù)制值)
2.拆箱指的是螟炫,把指向值的對象還原成該值波附。(復(fù)制值)
裝箱
var a = 'str'
a.toString()
當執(zhí)行toString()方法時,JS會自動將其包裝成String對象再調(diào)用方法.過程如下:
{ // 偽代碼
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'
}
類型轉(zhuǎn)換時會經(jīng)常發(fā)生裝箱和拆箱操作,需要注意