摘要:類型轉(zhuǎn)換法則這里討論里對(duì)不同類型進(jìn)行運(yùn)算的時(shí)候,是如何做類型轉(zhuǎn)換的一般是隱式轉(zhuǎn)換。轉(zhuǎn)化過程先查看對(duì)象的方法是否返回基本類型。結(jié)果轉(zhuǎn)為返回字符串。引用類型需先轉(zhuǎn)換為基本類型。后記不同類型之間的類型轉(zhuǎn)換,確實(shí)是讓人撓頭的語言。
Javascript為什么會(huì)有類型轉(zhuǎn)換
Javascirpt世界里,不推薦大量的使用try...catch...,我想大概原因:
JS里任何類型之間的算數(shù)運(yùn)算,邏輯運(yùn)算和位運(yùn)算都不會(huì)拋異常或者錯(cuò)誤。例如 1/0 == Infinity, 0/0 = NaN, [ ] + 1 = "1" 等。所以catch到excepton/error的幾率,相對(duì)于編譯型語言甚至于python/ruby等動(dòng)態(tài)語言,是大大地降低了。
try...catch...會(huì)在catch里轉(zhuǎn)換到一個(gè)新的作用域,catch里面調(diào)用本函數(shù)或者函數(shù)外的對(duì)象時(shí),增加了一層作用域的查找,降低了運(yùn)行效率
如果有未知的風(fēng)險(xiǎn),確實(shí)可以try...catch...。但是如果你的代碼里有比較多的try...catch...,這就是bad smell,說明需要加強(qiáng)coding質(zhì)量或者重構(gòu)了。
類型轉(zhuǎn)換法則這里討論JS里對(duì)不同類型進(jìn)行運(yùn)算的時(shí)候,是如何做類型轉(zhuǎn)換的(一般是隱式轉(zhuǎn)換)。
加法運(yùn)算1 + "-1" = "1-1"
基本類型之間相加時(shí),只要其一是字符串,另外一個(gè)也會(huì)先轉(zhuǎn)換為字符串,結(jié)果就變成字符串的連接。
[ ] + 1 = "1"
引用類型和基本類型相加。引用類型先轉(zhuǎn)化為基本類型。轉(zhuǎn)化過程:先查看對(duì)象的valueOf()方法是否返回基本類型。數(shù)組的valueOf返回它本身,屬于object類型,不是基本類型。所以再調(diào)用toString方法。空數(shù)組[]的toString返回空字符串。結(jié)果轉(zhuǎn)為‘’ + 1. 返回字符串‘1’。
[ ] + { } = [object Object]
引用類型之間的加法。引用類型需先轉(zhuǎn)換為基本類型。 參考2,空數(shù)組[]轉(zhuǎn)為空字符串。類似地空對(duì)象{ } 轉(zhuǎn)換時(shí),也先查看{ }.valueOf(). 因?yàn)?{}的valueof方法返回它自身,所以會(huì)調(diào)用{}.toString()返回‘[object Object]"。
這樣結(jié)果變成 "" + "[object Object]" = "[object Object]"
1 + null = 1
因?yàn)橐呀?jīng)是基本類型,而且沒有字符串,所以會(huì)基于number類型運(yùn)算。 null轉(zhuǎn)為0, 結(jié)果是 1 + 0 = 1
1 + undefined = NaN
undefined 轉(zhuǎn)為NaN, so 1+ NaN = NaN
false + null = 0
都是基本類型而且沒有字符串,所以基于數(shù)字類型相加。 false轉(zhuǎn)為0, null也為0. 結(jié)果 0 + 0 = 0
[1] + [2] = "12"
分別調(diào)用toString方法以轉(zhuǎn)為基本類型,得到"1"和‘2’, "1" + "2" = "12"
加法以外的算數(shù)運(yùn)算,如果有object類型(包括數(shù)組),先轉(zhuǎn)為基本類型,這和加法運(yùn)算是相同的。轉(zhuǎn)換過程也是先查看valueOf是否返回基本類型,如果不是,就調(diào)用toString(這里假定toString都返回string。除非誰閑著沒事,非得給一對(duì)象的toString返回對(duì)象類型?)
和加法運(yùn)算不同的是,轉(zhuǎn)換為基本類型后,所有的基本類型再轉(zhuǎn)為number類型,最終以number類型進(jìn)行運(yùn)算。
1 - "-1" = "-1"
字符串“-1”轉(zhuǎn)為number的-1, 結(jié)果1 - (-) = 2
[ ] - 1 = -1
[ ]先轉(zhuǎn)為基本類型,是空字符。空字符再轉(zhuǎn)為number為0 ,結(jié)果是0 - 1 = -1
[ ] / { }
空數(shù)組轉(zhuǎn)為基本類型是空字符,空對(duì)象轉(zhuǎn)為基本類型是[object Object],二者再分別轉(zhuǎn)為數(shù)字類型是 0 和 NaN,最終結(jié)果為0/NaN = NaN
1 / null
都已經(jīng)為基本類型,所以只要把null轉(zhuǎn)為number類型的0, 然后1 / 0 = Infinity
1 * undefined
都已經(jīng)為基本類型,所以只要把undefined轉(zhuǎn)為number類型的NaN, 然后1 * NaN = NaN
1 && null = null.
因?yàn)? 是真值,則返回第二個(gè)值, 即null
null && undefined = null
返回null,因?yàn)閚ull是falsy,則返回第一個(gè)。
0 || {} = {}
返回 {}. 因?yàn)? 是falsy,返回第二個(gè)
1 || null = 1
返回1, 因?yàn)?是真值,返回第一個(gè)
~n = -(n+1),
例如~25 = -26. 這里是帶符號(hào)的取反。如果是無符號(hào)的取反,結(jié)果就不一樣了,有興趣的可以在C語言里試試 ~25u
~null = -1
null轉(zhuǎn)為0, ~0 = -(0+1) =-1
~undefined //SyntaxError: Invalid or unexpected token
~~23.5 = 23 ~~-23.5 = -23
但 Math.floor(-23.5) = -24. 故而一般用~~取整數(shù)位
if(-1) 和if (-1 == true) 是不一樣的。前者是真假判斷: -1是truthy,是真值。后者類似算術(shù)運(yùn)算:先轉(zhuǎn)為number,true 轉(zhuǎn)為1, 故而 -1 == 1是假值。
小結(jié)這里總結(jié)了js類型轉(zhuǎn)換和運(yùn)行的基本規(guī)律,希望是可以滿足基本的項(xiàng)目需要了。
后記JS不同類型之間的類型轉(zhuǎn)換,確實(shí)是讓人撓頭的語言。我猜想可能是JS產(chǎn)生的時(shí)候,web方興未艾,web工程師的編程功底還沒有很規(guī)范(至少?zèng)]有今天這么多資料書籍和培訓(xùn)機(jī)構(gòu)等),所以js允許類型轉(zhuǎn)換,不同類型之間運(yùn)算時(shí),保證不拋異常或者盡量少拋。
但是現(xiàn)在前端和后端一樣的龐大了,顯然js的這樣那樣的技法往往會(huì)使工程師掉入陷阱。typescript應(yīng)允而生,一個(gè)目的是也是幫助初級(jí)工程師寫出還可以的代碼(另外一個(gè)目的估計(jì)是降低后端開發(fā)者寫前端的門檻和思維轉(zhuǎn)變)。從這角度解讀,ts也是為滿足項(xiàng)目工程和公司的需要。如果想深入js學(xué)習(xí),原生的js(es5/6)是繞不開的。
補(bǔ)證前面提到“try...catch...會(huì)在catch里轉(zhuǎn)換到一個(gè)新的作用域”,這是在《你不知道的JavaScript》中卷里看到的。后來感覺還是做些論證,否則老覺得不踏實(shí)。看如下代碼:
function testException() { var error = "outer error" try { throw "inner error" } catch (error) { console.log(error) error = "modify inner error" } // 這里會(huì)輸出 outer error(而不是modify inner error), // 說明catch...里修改的error,不是testExecution()函數(shù)作用域里的,而是一個(gè)“新”作用域里的error // 所以我們可認(rèn)為,catch...創(chuàng)建了一個(gè)新的作用域。看來它和函數(shù)作用域的類似點(diǎn),都接受“參數(shù)” console.log(error) } testException()
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/83685.html
摘要:完整清單是中添加,此處不予介紹布爾值用來表示可能是真或假的值。結(jié)果抽象比較運(yùn)算符在比較它們之前在類型之間進(jìn)行自動(dòng)轉(zhuǎn)換。中的隱式轉(zhuǎn)換稱為強(qiáng)制類型轉(zhuǎn)換,并在規(guī)范中定義。這些內(nèi)置類型可用于在不同類型之間進(jìn)行顯式轉(zhuǎn)換。 翻譯:瘋狂的技術(shù)宅原文:https://www.valentinog.com/bl... 本文首發(fā)微信公眾號(hào):前端先鋒歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 show...
摘要:強(qiáng)制類型轉(zhuǎn)換作為程序員,你一定獲取過當(dāng)前系統(tǒng)的時(shí)間戳。比如對(duì)于變量而言,此次強(qiáng)制類型轉(zhuǎn)換是隱式的。然而則是非常典型的顯式強(qiáng)制類型轉(zhuǎn)換。隱式強(qiáng)制類型轉(zhuǎn)換大部分被詬病的強(qiáng)制類型轉(zhuǎn)換都是隱式強(qiáng)制類型轉(zhuǎn)換。 JavaScript 強(qiáng)制類型轉(zhuǎn)換 作為 JavaScript 程序員,你一定獲取過當(dāng)前系統(tǒng)的時(shí)間戳。在 ES5 引入 Date.now() 靜態(tài)方法之前,下面這段代碼你一定不會(huì)陌生: v...
摘要:具體的行為取決于參數(shù)的類型。說到,就不得不提一下方法,方法自帶隱式類型轉(zhuǎn)換,該方法在測(cè)試其參數(shù)之前,會(huì)先調(diào)用方法將其轉(zhuǎn)換為數(shù)字。全等運(yùn)算符會(huì)先進(jìn)行數(shù)據(jù)類型判斷,并且不會(huì)發(fā)生隱式類型轉(zhuǎn)換。 類型轉(zhuǎn)換還不行?還非得隱式?這是什么高級(jí)玩意? 廢話不多說,我們先上一盤?,額,不對(duì),先看一個(gè)例子吧。 3 + true 實(shí)際上在大多數(shù)編程語言中,都會(huì)認(rèn)為上面這個(gè)表達(dá)式是錯(cuò)誤的。因?yàn)椴紶柋磉_(dá)式與算術(shù)...
摘要:第十七天筆記類型轉(zhuǎn)換隱式類型轉(zhuǎn)換隱式類型轉(zhuǎn)換是弱類型松散類型的在任何情況下都可以強(qiáng)制轉(zhuǎn)換定義類型類型以及類型的變量臥龍前端轉(zhuǎn)換為類型轉(zhuǎn)換為類型類型轉(zhuǎn)換為類型如果文本內(nèi)容是普通的文本非數(shù)字轉(zhuǎn)換后的結(jié)果為如果文本內(nèi)容是數(shù)字值轉(zhuǎn)換后的結(jié)果為對(duì) 第十七天筆記 類型轉(zhuǎn)換 隱式類型轉(zhuǎn)換 隱式類型轉(zhuǎn)換 JavaScript是弱類型/松散類型的 在任何情況下都可以強(qiáng)制轉(zhuǎn)換 //定義number類型 s...
摘要:日期類定義的方法會(huì)返回它的一個(gè)內(nèi)部表示年月日以來的毫秒數(shù)。和應(yīng)用的對(duì)象到原始值的轉(zhuǎn)換包含日期對(duì)象的一種特殊情形。簡(jiǎn)單說與引發(fā)的思考簡(jiǎn)單說通過的隱式轉(zhuǎn)換,關(guān)鍵時(shí)刻救你一命 說明 所有的對(duì)象都繼承有toString() 和 valueOf() 方法,對(duì)象到字符串,對(duì)象到數(shù)字的轉(zhuǎn)換,會(huì)通過調(diào)用待轉(zhuǎn)換對(duì)象的這兩個(gè)方法中的一個(gè)來完成。 解釋 toString( )方法的作用是: 返回一個(gè)反映這個(gè)...
摘要:日期類定義的方法會(huì)返回它的一個(gè)內(nèi)部表示年月日以來的毫秒數(shù)。和應(yīng)用的對(duì)象到原始值的轉(zhuǎn)換包含日期對(duì)象的一種特殊情形。簡(jiǎn)單說與引發(fā)的思考簡(jiǎn)單說通過的隱式轉(zhuǎn)換,關(guān)鍵時(shí)刻救你一命 說明 所有的對(duì)象都繼承有toString() 和 valueOf() 方法,對(duì)象到字符串,對(duì)象到數(shù)字的轉(zhuǎn)換,會(huì)通過調(diào)用待轉(zhuǎn)換對(duì)象的這兩個(gè)方法中的一個(gè)來完成。 解釋 toString( )方法的作用是: 返回一個(gè)反映這個(gè)...
閱讀 1588·2019-08-30 13:18
閱讀 1578·2019-08-29 12:19
閱讀 2094·2019-08-26 13:57
閱讀 4137·2019-08-26 13:22
閱讀 1179·2019-08-26 10:35
閱讀 2991·2019-08-23 18:09
閱讀 2500·2019-08-23 17:19
閱讀 677·2019-08-23 17:18