摘要:通過(guò)拆箱轉(zhuǎn)換,把對(duì)象編程基本類(lèi)型,再?gòu)膹幕绢?lèi)型轉(zhuǎn)換成對(duì)應(yīng)的或者。拆箱轉(zhuǎn)換會(huì)嘗試調(diào)用和來(lái)獲得拆箱后的基本類(lèi)型。
undefined和null
??Undefined類(lèi)型表示未定義,它的類(lèi)型只有一個(gè)值為undefined。任何變量在賦值前都是undefined類(lèi)型,值為undefined。但是JS中undefined是一個(gè)變量,并非是一個(gè)關(guān)鍵字,為了避免無(wú)意中的篡改,使用void 0來(lái)獲取undefined值。
??undefined和null有一定的表意差別,null表示“定義了但是為空”,它只一個(gè)值為null,并且是JS關(guān)鍵字,可以放心使用。
Number??非整數(shù)的Number類(lèi)型無(wú)法使用 == 或 === 來(lái)比較,有一段著名的代碼
console.log(0.1 + 0.2 == 0.3);
??輸出結(jié)果是false,說(shuō)明兩邊不等,這是浮點(diǎn)運(yùn)算的特點(diǎn),浮點(diǎn)數(shù)運(yùn)算的精度問(wèn)題導(dǎo)致等式左右并不是嚴(yán)格相等,而是相差了個(gè)微小的值。
??正確的比較方法是使用JS提供的最小精度值:
console.log(Math.abs(0.1 + 0.2 -0.3) <= Number.EPSILON);
??檢查等式左右兩邊差的絕對(duì)值是否小于最小精度值,才是正確的比較浮點(diǎn)數(shù)的方法。
類(lèi)型轉(zhuǎn)換??因?yàn)?JS 是弱類(lèi)型語(yǔ)言,所以類(lèi)型轉(zhuǎn)換發(fā)生非常頻繁,大部分我們熟悉的運(yùn)算都會(huì)先進(jìn)行類(lèi)型轉(zhuǎn)換。大部分類(lèi)型轉(zhuǎn)換符合人類(lèi)的直覺(jué),但是如果我們不去理解類(lèi)型轉(zhuǎn)換的嚴(yán)格定義,很容易造成一些代碼中的判斷失誤。其中最為臭名昭著的是 JS 中的“ == ”運(yùn)算,因?yàn)樵噲D實(shí)現(xiàn)跨類(lèi)型的比較,它的規(guī)則太過(guò)復(fù)雜。很多實(shí)踐中推薦禁止使用“ ==”,而要求程序員進(jìn)行顯式地類(lèi)型轉(zhuǎn)換后,用 === 比較。
??parseInt 和 parseFloat 是很常用的類(lèi)型轉(zhuǎn)換的方法。在不傳入第二個(gè)參數(shù)的情況下,parseInt 只支持 16 進(jìn)制前綴“0x”,而且會(huì)忽略非數(shù)字字符,也不支持科學(xué)計(jì)數(shù)法。在一些古老的瀏覽器環(huán)境中,parseInt 還支持 0 開(kāi)頭的數(shù)字作為 8 進(jìn)制前綴,這是很多錯(cuò)誤的來(lái)源。所以在任何環(huán)境下,都建議傳入 parseInt 的第二個(gè)參數(shù),而 parseFloat 則直接把原字符串作為十進(jìn)制來(lái)解析,它不會(huì)引入任何的其他進(jìn)制。
??多數(shù)情況下,Number 是比 parseInt 和 parseFloat 更好的選擇。
裝箱轉(zhuǎn)換??每一種基本類(lèi)型 Number、String、Boolean、Symbol 在對(duì)象中都有對(duì)應(yīng)的類(lèi),所謂裝箱轉(zhuǎn)換,正是把基本類(lèi)型轉(zhuǎn)換為對(duì)應(yīng)的對(duì)象,它是類(lèi)型轉(zhuǎn)換中一種相當(dāng)重要的種類(lèi)。全局的 Symbol 函數(shù)無(wú)法使用 new 來(lái)調(diào)用,但我們?nèi)钥梢岳醚b箱機(jī)制來(lái)得到一個(gè) Symbol 對(duì)象,我們可以利用一個(gè)函數(shù)的 call 方法來(lái)強(qiáng)迫產(chǎn)生裝箱。我們定義一個(gè)函數(shù),函數(shù)里面只有 return this,然后我們調(diào)用函數(shù)的 call 方法到一個(gè) Symbol 類(lèi)型的值上,這樣就會(huì)產(chǎn)生一個(gè) symbolObject。
??我們可以用 console.log 看一下這個(gè)東西的 type of,它的值是 object,我們使用 symbolObject instanceof 可以看到,它是 Symbol 這個(gè)類(lèi)的實(shí)例,我們找它的 constructor 也是等于 Symbol 的,所以我們無(wú)論哪個(gè)角度看,它都是 Symbol 裝箱過(guò)的對(duì)象:
var symbolObject = (function(){ return this; }).call(Symbol("a")); console.log(typeof symbolObject); //object console.log(symbolObject instanceof Symbol); //true console.log(symbolObject.constructor == Symbol); //true
??裝箱機(jī)制會(huì)頻繁產(chǎn)生臨時(shí)對(duì)象,在一些對(duì)性能要求較高的場(chǎng)景下,我們應(yīng)該盡量避免對(duì)基本類(lèi)型做裝箱轉(zhuǎn)換。
??使用內(nèi)置的Object函數(shù),可以在JS代碼中顯式的調(diào)用裝箱能力。
var symbolObject = Object((Symbol("a")); console.log(typeof symbolObject); //object console.log(symbolObject instanceof Symbol); //true console.log(symbolObject.constructor == Symbol); //true
??每一類(lèi)裝箱對(duì)象皆有私有的Class屬性,這些屬性可以用Object.protoype.toString獲取:
var symbolObject = Object((Symbol("a")); console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]
??JS中,沒(méi)有方法可以更改私有的Class屬性,因此Object.prototype.toString是可以準(zhǔn)確識(shí)別對(duì)象對(duì)應(yīng)的基本類(lèi)型的方法,它比instanceof更加準(zhǔn)確。
??但需要注意的是,call 本身會(huì)產(chǎn)生裝箱操作,所以需要配合typeof來(lái)區(qū)分基本類(lèi)型還是對(duì)象類(lèi)型。
拆箱轉(zhuǎn)換??JS標(biāo)準(zhǔn)中,規(guī)定了ToPrimitive函數(shù),它是對(duì)象類(lèi)型到基本類(lèi)型的轉(zhuǎn)換。(即拆線轉(zhuǎn)換)
??對(duì)象到String和Number的轉(zhuǎn)換都遵循“先拆箱再轉(zhuǎn)換”的規(guī)則。通過(guò)拆箱轉(zhuǎn)換,把對(duì)象編程基本類(lèi)型,再?gòu)膹幕绢?lèi)型轉(zhuǎn)換成對(duì)應(yīng)的String或者Number。
??拆箱轉(zhuǎn)換會(huì)嘗試調(diào)用valueOf和toString來(lái)獲得拆箱后的基本類(lèi)型。如果valueOf和toString都不存在。或者沒(méi)有返回基本類(lèi)型,則會(huì)產(chǎn)生類(lèi)型錯(cuò)誤的提示TypeError。
var o = { valueOf : () => {console.log("valueOf"); return {}}, toString : () => {console.log("toString"); return {}} } o * 2 // valueOf // toString // TypeError
??我們定義了一個(gè)對(duì)象 o,o 有 valueOf 和 toString 兩個(gè)方法,這兩個(gè)方法都返回一個(gè)對(duì)象,然后我們進(jìn)行 o * 2 這個(gè)運(yùn)算的時(shí)候,你會(huì)看見(jiàn)先執(zhí)行了 valueOf,接下來(lái)是 toString,最后拋出了一個(gè) TypeError,這就說(shuō)明了這個(gè)拆箱轉(zhuǎn)換失敗了。
??到 String 的拆箱轉(zhuǎn)換會(huì)優(yōu)先調(diào)用 toString。我們把剛才的運(yùn)算從 o*2 換成 o + “”,那么你會(huì)看到調(diào)用順序就變了。
var o = { valueOf : () => {console.log("valueOf"); return {}}, toString : () => {console.log("toString"); return {}} } o + "" // toString // valueOf // TypeError
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102397.html
摘要:的碼點(diǎn)被稱(chēng)為基本字符區(qū)域。關(guān)于的介紹,我準(zhǔn)備用文檔阮一峰來(lái)做一些介紹,具體的可以參考文檔引入的原因的對(duì)象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數(shù)前不能使用命令,否則會(huì)報(bào)錯(cuò)。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完...
摘要:的碼點(diǎn)被稱(chēng)為基本字符區(qū)域。關(guān)于的介紹,我準(zhǔn)備用文檔阮一峰來(lái)做一些介紹,具體的可以參考文檔引入的原因的對(duì)象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數(shù)前不能使用命令,否則會(huì)報(bào)錯(cuò)。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完...
摘要:的碼點(diǎn)被稱(chēng)為基本字符區(qū)域。關(guān)于的介紹,我準(zhǔn)備用文檔阮一峰來(lái)做一些介紹,具體的可以參考文檔引入的原因的對(duì)象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數(shù)前不能使用命令,否則會(huì)報(bào)錯(cuò)。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完...
摘要:前端增長(zhǎng)重新定義大前端精心打造全新課程,歡迎吐槽反饋寶貴意見(jiàn)在線課程前端增長(zhǎng)你不知道的那些細(xì)節(jié)附贈(zèng)常見(jiàn)核心前端面試問(wèn)題與詳細(xì)解答官方博客前端學(xué)堂課件腦圖下載課程介紹前端知識(shí)點(diǎn)很多,很細(xì)碎。 showImg(https://segmentfault.com/img/bVbu250?w=500&h=497);前端增長(zhǎng)-重新定義大前端 精心打造全新課程,歡迎吐槽!反饋寶貴意見(jiàn)! 在線課程:前...
閱讀 3063·2021-11-24 10:34
閱讀 3322·2021-11-22 13:53
閱讀 2630·2021-11-22 12:03
閱讀 3598·2021-09-26 09:47
閱讀 3005·2021-09-23 11:21
閱讀 4772·2021-09-22 15:08
閱讀 3290·2021-07-23 10:59
閱讀 1258·2019-08-29 18:31