最近在寫公司的登陸註冊模塊,遇到類型不一樣相比較的時候,就心驚膽戰,每次都要用瀏覽器來驗證一下,決定亂七八糟的隨便寫一下,方便往後本身回顧知識~正則表達式
弱類型帶來的好處之一:終於不用本身肯定數據類型了。數組
寫C++這類的強類型語言,每次都要先肯定是int
、char
仍是string
之類的,可是僅僅經過var
,怎麼解決工做過程當中的不一樣數據類型的比較問題的呢?瀏覽器
這個問題煩了我好久,當初學js的時候就只能記住最簡單的其餘類型到boolean
的轉換,涉及到其餘的,只能暈菜。。。函數
下面分幾步來簡單的探探不一樣類型的轉換吧~性能
如下的內容,均可以從《JavaScript權威指南》中找到。學習
boolean
在編寫JavaScript代碼的過程當中,幾乎不用考慮它的取值類型。在工做過程當中,咱們有可能會須要在if
的條件判斷中對參數進行判斷,這就涉及到了boolean
值的轉換。spa
當JavaScript指望使用一個布爾值的時候,你能夠提供任意類型值,JavaScript將根據須要自行轉換類型,一些值(真值)轉爲
true
,其餘值(假值)轉爲false
--《JavaScript權威指南》(page 48)prototype
對於布爾值類型的轉換,實際上只須要特別記住幾個特殊的會轉換成false
的值就能夠了3d
這些值包括:undefined
、null
、false
、""
、0
、-0
、NaN
code
全部的其餘值(包括全部對象)都會轉換成true
通常在工做中,咱們能夠直接使用:
if (value){ ... }
根據js的語言特性,可讓瀏覽器直接替咱們判斷,省時省力,我我的不太喜歡下面的寫法:
if (value == null){ ... }
儘管這樣也能夠達成目標,可是總感受多敲了代碼,還須要特別注意若是不是null
或者undefined
,但也是假值的狀況。
須要特別注意:假值中包含0
or -0
的狀況
還有一個小點須要特別注意一下:jQuery
中選擇符選擇某個DOM節點,也許這個DOM節點並不存在,可是$(selector)
返回的值是一個對象,因此,咱們判斷是否存在這個DOM,須要經過$(selector).length > 0
來判斷是否存在。
原始值:數字
、字符串
、布爾值
、null
、undefined
原始值轉換成字符串的狀況估計是最簡單的了,能夠直接理解成在原始值的兩邊加上""
就好了
undefined --> "undefined" null --> "null" true --> "true" false --> "false" 0 --> "0" -0 --> "-0" NaN --> "NaN" Infinity --> "Infinity" -Infinity --> "-Infinity" 1 --> "1" ......
除了字符串,大部分原始值都會有固定的轉換結果,以下:
undefined --> NaN null --> 0 true --> 1 false --> 0
可是,字符串的轉換有點微妙,給個人感受有點相似Number()
方法,可是注意,只是相似,調用Number()
會生成包裝對象,而不是一個數字。
字符串轉換成數字,會有如下的特色:
以數字表示的字符串能夠直接轉換成數字
容許字符串開頭跟結尾帶有空格
在開始和結尾處的任意非空格符都不會被當成數字直接量的一部分,轉換結果變成NaN
結果以下:
"one" --> NaN "u123" --> NaN " 123" --> 123 "123 " --> 123 " 12 " --> 12
原理:原始值經過調用String()
、Number()
、Boolean()
構造函數,轉換成他們各自的包裝對象
存取字符串、數字或者布爾值的屬性的時候建立的臨時對象叫作包裝對象,他只是偶爾用來區分字符串值和字符串對象、數字和數值對象以及布爾值布爾對象。一般,包裝對象只是被看作是一種實現細節,而不用特別關注。--《JavaScript權威指南》(page46)
可是null
和undefined
信仰比較堅決,就是不想轉成對象,從而,當將它們用在指望是一個對象的地方都會拋出一個錯誤throws TypeError
注意:只是在轉換的過程當中會拋出Error
,在顯性建立對象的時候,不會報錯
對象轉換成原始值,能夠分紅如下三種:
對象轉換成boolean
值
對象轉換成字符串(object-to-string)
對象轉換成數字(object-to-number)
其中,對象轉換成boolean
值,規則很是簡單:全部的對象都轉換成true
(包括包裝對象)
注意:new Boolean(false)
是一個對象,轉換成布爾值也是true
而對象轉換成字符串以及對象轉換成數字根據場景不一樣,有些複雜,在學習瞭解他們的轉換過程以前,先來看兩個函數:toString()
以及valueOf()
一、在MDN中搜索toString
,你會發現以下情形:
若是細細查看,你會發現:全部的對象都有toString()
方法,做用就是返回一個反映這個對象的字符串。
可是,這個方法返回的值有些時候不是那麼的好。
例如:Object.prototypr.toString()
默認狀況下,每一個對象都會從Object
上繼承到toString()
方法,若是這個方法沒有被這個對象自身或者更接近的上層原型上的同名方法覆蓋(遮蔽),則調用該對象的toString()
方法時會返回"[object type]"
,這裏的字符串type表示了一個對象類型。
例如:
var o = new Object(); o.toString() //返回[object Object]
不少類定義了不少特定版本的toString()
方法:
數組類Array.prototype.toString()
函數類Function.prototype.toString()
日期類Date.prototype.toString()
正則類RegExp.prototype.toString()
······
使用方法及返回結果以下:
二、在MDN搜索valueOf
,能夠獲得與toString
類似的結果。
可是,這個方法的任務並無詳細的定義,我甚至沒法從MDN的描述中得出它與toString
的區別。
JavaScript calls the
valueOf
method to convert an object to a primitive value. You rarely need to invoke the valueOf method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.
也許從下面的代碼中咱們能夠初窺一二:
[1,2,3].toString() // --> "1,2,3" [1,2,3].valueOf() // --> [1, 2, 3] (function(x){f(x);}).toString() // --> "function (x){f(x);}" (function(x){f(x);}).valueOf() // --> function anonymous(x) /\d+/g.toString() // -->"/\d+/g" /\d+/g.valueOf() // --> /\d+/g new Date(2010,0,1).toString() // --> "Fri Jan 01 2010 00:00:00 GMT+0800 (中國標準時間)" new Date(2010,0,1).valueOf() // --> 1262275200000
根據上面的結果,能夠嘗試得出如下的結論:
對象是複合值,並且大多數對象沒法真正表示爲一個原始值,所以默認的`valueOf()`方法簡單地返回對象自己,而不是返回一個原始值
數組、函數以及正則表達式簡單地繼承了這個默認的方法,而日期類定義的valueOf()
方法返回它的一個內部表示:1970年1月1日以來的毫秒數
有了上面的兩個方法,咱們就能夠進行對象到字符串以及對象到數字的轉換了。
對象到字符串的轉換的步驟以下:
若是對象具備toString()
方法,那麼就調用這個方法,返回一個原始值,若是這個值自己不是字符串,JavaScript
會將其轉換成字符串,並返回字符串的結果。
若是沒有toString()
方法,或者這個方法不返回一個原始值,那麼調用valueOf()
方法,返回一個原始值,若是這個值自己不是字符串,JavaScript
會將其轉換成字符串,並返回字符串的結果。
不然JavaScript
沒法從toString()
或者valueOf()
得到一個原始值,這時拋出一個類型錯誤。
對象到數字的轉換的步驟以下:
若是對象具備valueOf()
方法,那麼就調用這個方法,返回一個原始值,若是這個值自己不是字符串,JavaScript
會將其轉換成字符串,並返回字符串的結果。
若是沒有valueOf()
方法,或者這個方法不返回一個原始值,那麼調用toString()
方法,返回一個原始值,若是這個值自己不是字符串,JavaScript
會將其轉換成字符串,並返回字符串的結果。
不然JavaScript
沒法從toString()
或者valueOf()
得到一個原始值,這時拋出一個類型錯誤。
因爲JavaScript
是弱類型語言,因此咱們對於類型轉換的應用其實有許多。
例如:if
判斷、+
運算符以及==
運算符等等
關於+
:
進行數字加法以及字符串鏈接操做
若是其中的一個操做數是對象,則將對象轉換成原始值
==
也是js判斷中經常使用的涉及到類型轉換的一個運算符
關於==
:
若是兩個值類型相同,進行===
比較
若是兩個值類型不一樣,他們可能相等,須要按照必定的規則來進行類型轉換並比較
==
類型不一樣時的轉換規則:
若是一個值是null
,另外一個值是undefined
,則相等
若是一個是字符串
,另外一個值是數字
,則把字符串
轉換成數字
,進行比較
若是任意值是true
,則把true
轉換成1
再進行比較;若是任意值是false
,則把false
轉換成0
再進行比較
若是一個是對象
,另外一個是數值
或字符串
,把對象
轉換成基礎類型
的值再比較。對象
轉換成基礎類型
,利用它的toString
或者valueOf
方法。 js核心內置類,會嘗試valueOf
先於toString
(能夠理解爲對象優先轉換成數字);例外的是Date
,Date
利用的是toString
轉換。非js核心的對象,經過本身的實現中定義的方法轉換成原始值
關於比較運算符<
、|
、>
、|
、<
、=
、|
、>
、=
若是操做數爲對象,那麼這個對象將轉換成原始值:若是valueof()
返回一個原始值,那麼直接使用這個原始值。不然,使用toString()
的轉換結果進行比較操做
在對象轉換成原始值以後,若是兩個操做數都是字符串,那麼將按照字母表的順序對兩個字符串進行比較,字母表的順序是指組成這個字符串的16位unicode
字符的索引順序。注意:字符串比較是區分大小寫的,全部大寫的ASCII字母都小於全部小寫的ASCII字母
在對象轉換成原始值以後,若是至少有一個操做數不是字符串,那麼兩個操做數都將轉換成數字進行數值比較。0
與-0
是相等的。Infinity
比其餘任何數字都大(除了Infinity
自己),-Infinity
比其餘任何數字都要小(除了它自己)。若是其中一個操做數是(或轉換後是)NaN
,那麼比較操做符老是返回false
加號運算符與比較運算符的區別
加法運算符更偏心字符串的操做,比較運算符更偏心數字
只有兩個操做數都是字符串,才進行字符串的比較
1+2 //加法,結果是3 "1"+"2" //字符串鏈接,結果是"12" "1"+2 //字符串鏈接,結果是"12" 11 < 2 //數字的比較,結果是false "11" < "3" //字符串比較,結果爲true "11" < 3 // 數字比較,"11"轉換成11,結果爲false "one" < 3 //數字的比較,"one"轉換成NaN,結果爲false
注意:<=
以及>=
在判斷相等的狀況的時候,並不依賴相等或者嚴格相等運算符的比較規則,它們只是簡單的不大於
、不小於
昨天公司的一件事對個人觸動挺大的,公司裏面的兩個後臺爲了表單提交是用GET
仍是POST
爭吵了半個小時。有些時候,不經意就會忽略一些問題,好比代碼的質量,性能的提升,這些都是值得程序猿們深刻探究的問題。
記得有過這樣一句話「你對待技術的態度,就是你對待生命的態度」。
做爲一名小猿,繼續奮鬥去嘍~