上一章主要講了轉換到數字,字符串和布爾類型的一些知識點,那麼這一講接着上面的繼續講。javascript
思考下面這個問題:java
console.log(+"123"); // 123 console.log(-"123"); // -123 console.log(+"abc"); // NaN console.log(-"abc"); // NaN
+這個很容易理解,就是把字符串轉成了數字,而-這個呢,除了把字符串轉爲數字之外,還會吧這個數字加否。因此不管+仍是-都會進行類型轉換,惟一的區別,就是-會置否而+不會。數組
那麼+除了看成一元運算符外,還有一個更廣爲人知的就是做爲加法運算符。函數
那麼加法運算符的話,其實是有兩種可能性的,一種是字符串的拼接,另外一種就是作運算。接下來我們就對這方面詳細的講解一下。工具
先說結論,若是在+的其中有一個操做數是字符串或者能夠轉爲字符串的話,那麼就進行字符串拼接。code
反之,若是倆都是數字的話,則進行加法運算。對象
這時候,確定會有人問,假如說我有其餘的數據類型呢,又不是數字又不是字符串,好比說數組啊,對象啊,布爾值啥的,ip
那麼若是是引用數據類型,則先轉爲基本數據類型,再進行比較。文檔
若是是布爾呢,若是加法的另外一邊是數字的話,那麼他就會轉爲數字,若是是字符串的話,就直接拼接啦.字符串
上面說了一大堆的理論的東西,想必你們看着也累了。來上例子。
console.log(true + 11); // 12 console.log(true + false); // 1 console.log(true + '11'); // "true11"
這個很明顯能夠看出,若是操做數是數字的話,或者說,操做數都是字符串的話,那麼布爾值會先轉爲數字,再進行拼接操做,若是有一個操做數是字符串的話,那就不轉啦,直接拼接。
那麼若是是對象類型,它是先轉爲基本數據類型,怎麼轉呢,其實就是先調用valueOf,若是valueOf不存在,或者返回的不是基本數據類型,就調用toString,若是toString也沒有或者是返回的不是基本數據類型呢,那估計就直接報錯了,看例子。
var obj = { valueOf() { return [2, 3]; }, toString() { return "sss"; } } var obj1 = { valueOf() { return 111; }, toString() { return "abc"; } } var obj2 = { valueOf() { return []; }, toString() { return { abc: 'liuhaitao', } } } console.log(obj + 1); // "sss1" console.log(obj1 + 1); // 112 console.log(obj2 + 1); // "Cannot convert object to primitive value"
那麼下面一個例子就很容易理解了。
console.log([1].valueOf()); // [1] console.log([1] + [2]); // 12
由於數組的valueOf的值依然爲數組,因此他們轉的時候,就會調用toString,因此就轉成了字符串啦,倆字符串進行拼接,獲得最終結果
減法運算符(-)
很顯然,減法運算符就是作減法的,他很單純,就只是作減法,可是呢,這個有一個知識點,就是,減法裏的操做數,若是不是數字的話,那麼會先轉爲數字類型的。
console.log("123" - 0); // 123 console.log([3] - [1]); // 2 console.log({valueOf() { return 3}} - {valueOf() { return 2}}); // 1
這個很明顯,第一個和第二個的結果都是轉爲了數字再進行運算的,那第三個呢,其實這個就是對象的轉化方式,若是有valueOf的話,會先執行valueOf找出基本類型值,沒有或者不是基本類型值就找toString,最後呢,吧基本類型值轉爲數字再進行減法運算 。
好了,加法和減法都說完了,那麼乘法和除法呢,其實和減法相似,都是轉爲數字這樣的。
console.log("123" * 0); // 0 console.log([3] * [1]); // 3 console.log({valueOf() { return 3}} * {valueOf() { return 2}}); // 6
想看乘法和除法其餘的細節和本文關係不是太大,因此就不細講了,詳情請查閱文檔ecma文檔:
https://www.ecma-internationa...
https://www.ecma-internationa...
還有本節最後一部分,就是有關於邏輯與(&&)和邏輯或(||)
爲啥要特意介紹他倆呢,由於他倆的語法和其餘語言的語法特性彷佛有那麼一些區別。來看代碼
var a = 42; var b = "abc"; var c = null; console.log(a || b); // 42 console.log(a && b); // "abc" console.log(c || b); // "abc" console.log(c && b); // null
這一塊能夠看出,他和其餘語言的不一樣之處在於,他的運算的結果,並非true和false,而是具體的值,也就是說
||符號的時候,若是第一個操做數是true,則返回第一個操做數,若是是false返回第二個,
&&相反,若是第一個操做數是true,則返回第二個操做數,若是是false則返回第一個。
那這個有啥用呢?
其實能夠利用這個的特性簡化咱們的代碼,好比說
function exec () { console.log('exec'); } true && exec(); // exec var a = undefined; var b = a || 10; console.log(b); // 10
這個表明了應用的兩個方面,&&能夠作函數執行的前置判斷,後面那個呢,能夠作缺省時的默認值,你能夠仔細觀察一下,在一些壓縮代碼工具,壓縮完後的代碼,不少都把if 條件判斷改爲了&&,此次知道緣由了吧。
參考書籍《你不知道的Javascript中卷》