天天多一點(2016.12.04)》Javascript隱式轉換

亂想

javascript爲何須要隱式轉換?若是沒有會出現什麼狀況?

找了一圈沒有看到關於這個的討論,只好本身研究了,可能不必定正確,自行辨知。javascript

鬱悶就是鬱悶在好好的,爲何要搞個隱式轉換,通常來說這樣去想不太可能想出個結果,畢竟這門語言不是本身寫的,若是換一個問題,可能會好點,若是沒有隱式轉換javscript會成什麼樣子?前端

好比下面這一段代碼:java

console.log("10" - 1)

若是沒有隱式轉換,也許會報錯吧?或者返回NaN?,不太肯定,但假如說javascript根本不存在隱式轉換,或許你不會這樣去寫代碼吧,那麼就更奇怪了,設計隱式轉換究竟何目的?目前能想到的一點就是由於它是一門動態語言,值是運行時才知道的,所以有不少不肯定的因素,這多是做者設計隱式轉換的目的吧。程序員

什麼是隱式轉換

console.log(1 + "2");//12

能夠看到一個是Number類型的值和一個String類型的值進行了相加,結果是12。那爲何是12呢?若是是按照數字相加應該是3,但這裏倒是將1和2進行了字符串拼接,也就是說這裏的1被轉換成了字符串1。後端

結論

若是兩個值(也能夠是多個)的類型不一樣,但你卻拿它們來運算,它們就會進行隱式轉換,固然也不僅是運算纔會產生隱式轉換。數組

誰被轉換

console.log(10 + "2");//102

console.log(10 - "2");//8
console.log(10 * "2");//20
console.log("2" - 10);//-8
console.log(10 / "2");//5

它們有一個小小的規律,若是是+號,數字會被轉換成字符串,而若是是減乘除則會將字符串轉換成數字。函數

那麼爲何惟獨+號比較特別呢,由於在javascript中,+號是有兩個做用的,一個是數字相加,另外一個是字符串拼接,而javscript默認把這種狀況當成了字符串拼接。另減乘除就不存在這種問題,所以也只好將字符串轉換成數字。編碼

哪些狀況下會進行隱式轉換

上面的幾個例子中,都是在講運算符致使的隱式轉換,那麼除了這種狀況還有哪些狀況下會進行隱式轉換?設計

某些函數

isNaN():code

console.log(isNaN(2)) //false
console.log(isNaN("a")) //true
console.log(isNaN("2")) //false

isNaN會將傳進來的那個值進行轉換若是可以轉換成數字那麼就是false(若是自己就是數字那麼也是false),不然true。

條件判斷
if(""){
  console.log(true); //不會被打印
}
if(" "){
  console.log(true); //會被打印
}

空字符串會被轉換成false,否空字符串會被轉換成true。

[0,-1,[],{},NaN,undefined,null,""," "].forEach(function(item,index){
  if(item){
    console.log(item);
  }
})

// 打印的有:-1,[],{}," "

也就是除,非0的數字,數組,對象,非空字符串都會被轉換成true,其餘的false。

須要注意的是switch不會進行隱式轉換

switch("5"){
  case 5:
    console.log(5);
    break;
  case "5":
    console.log("5"); //打印這條
    break;
}

若是switch會進行隱式轉換那麼問題就出大了,甚至咱們都不敢去使用它。那麼爲何if會進行隱式轉換,個人理解是,由於if它的值無非就是true跟false,而你傳進來的不是這種類型,它天然須要進行轉換,switch則不一樣,它判斷的是一個值是否是和另一個值相等,所以它不能去轉換,換一句話說switch使用的是 === 比較。

其餘類型的混合運算

相加

console.log([]+0); //0

console.log(!+0); //true
console.log(!+1); //false

console.log(NaN+2); //NaN
console.log(NaN+"2"); //NaN2
console.log(NaN+"a"); //NaNa

console.log(undefined+0); //NaN
console.log(undefined+"0"); //undefined0

console.log(null+0); //0
console.log(null+"0"); //null0

console.log({}+0); //[object Object]0
console.log({}+"0"); //[object Object]0

console.log(""+0); //0
console.log(""+"0"); //0

console.log(true + 0); //1
console.log(true + "0"); //true0

console.log(false + 0); //0
console.log(false + "0"); //false0
  • []》 0
  • !》 會將後面的那個值轉換成布爾類型,而後取反
  • undefined 》 根據後面的那個值來進行轉換,若是是數字轉換成NaN,不然字符串拼接
  • {} 》 [object Object]
  • true 》 1
  • false 》 0

其實有一個規律,除了[],{},其餘的值具體轉換是根據和它進行運算的那個值的類型來轉換的。

相減

console.log([]-0); //0

console.log(!-0); //true
console.log(!-1); //false

console.log(NaN-2); //NaN
console.log(NaN-"2"); //NaN
console.log(NaN-"a"); //NaN

console.log(undefined-0); //NaN
console.log(undefined-"0"); //NaN

console.log(null-0); //0
console.log(null-"0"); //0

console.log({}-0); //NaN
console.log({}-"0"); //NaN

console.log(""-0); //0
console.log(" "-"0"); //0
console.log("1"-"0"); //1

除了相加覺得,其餘的幾個運算符,主要仍是將這些值轉換成數字進行運算,比較特殊的是!(取反),它始終轉換成的是一個布爾值。

一些有趣的事

根據這些隱式轉換,有時咱們能夠用它來作一些不一樣尋常的事,好比直接利用隱式轉換來取得一個object字符串。

console.log(({}+0).substring(1,({}+0).indexOf(" "))) //object

原理由於{}+0等於 = "[object Object]0",既然它是一個字符串,那麼咱們能夠用字符串的方法,將其中的某個值取出來,也能夠用[]的方式來取值。

也就是利用這些隱式轉換你能夠取得任何字符串,甚至中文,不過須要你對javascript有點基礎罷了。

console.log(String.fromCharCode(20013)) //中

取中文須要你知道對應的字符串編碼值

隱式轉換帶來的利與弊

好處就是,咱們不須要直接顯示的進行轉換,好比你想將一個字符串轉成數字,只須要這樣:

console.log("15"-0) //數字15

傳統的作法

console.log(parseInt("15")) //數字15

但也有壞處,就是有些你並不但願進行轉換,但它卻轉換了,而每每你容易忘了它會進行隱式轉換這一點,致使一些不太明顯的bug。

總結

大體會進行隱式轉換的狀況以下:

一、不一樣類型的值進行運算
二、判斷
三、個別函數

問答

這兩年愈來愈多討論關於全棧工程師的話題,而實際上所謂的全棧工程師就是早期的程序員,那時分工沒有如今這麼明細,不少活都是一我的幹,後來纔開始分前端後端等,如今又開始所謂的全棧,你怎麼看?若是你想成爲一個全棧工程師,你會怎麼作?

相關文章
相關標籤/搜索