javascript的數據類型包括:
(1)基本數據類型:number、string、boolean、null、undefined
(2)對象:object
object又包括Function、Array、Date、ExgReg等
javascript的隱式類型轉換,是相對於顯示類型轉換來說的。
明確的將某種類型轉換成另一種類型稱為顯示轉換,相反則稱為隱式類型轉換。
顯示類型轉換的方法Number()、Boolean()、String()、toString() 等
隱式類型轉換包括運算、語句等
一、運算中的隱式類型轉換
1、遞增遞減操作符
遞增“++” 、 遞減“--” 運算符不僅適用於整數,還可以用於字符串、布爾值、浮點數值和對象。
轉換方式如下:
(1)是包含有效數字字符的字符串時,先將其轉換為數字值,再進行運算
(2)是不包含有效數字字符的字符串時,將其值轉換為NaN
(3)是布爾值時,false轉換為數值0,true轉換為數值1
(4)是對象時,先調用對象的valueOf()方法,以取得一個可供操作的值,如果結果是NaN,調用toString() 方法
var s1="1", s2="12abc", b=true, o={valueOf:function(){ return -1; } }; console.log(++s1);//2 console.log(++s2);//NaN console.log(++b);//2 console.log(++o);//0
2、一元加減操作符
一元加號(+)放在數值前面,對數值不會產生任何影響。
var num=25; num=+num;//還是25
在對非數值應用一元加操作符時,該操作符會像Number()轉型函數一樣對這個值執行轉換。
Number類型的轉換規則如下:
(1)如是布爾值,true轉換為1,false轉換為0
(2)如是null,返回0
(3)如是undefined,返回NaN
(4)如是字符串,規則
- 如字符串中只包含數字(包括前面帶正負號的情況),將其轉換為十進制數值
- 如字符串中包含有效的浮點格式,將其轉換為對應的浮動數值
- 如字符串中包含有效的十六進制格式,例如“oxf”,將其轉換為相同大小的十進制整數值
- 如字符串為空,轉換為0
- 如字符中包含除上述格式之外的字符,將其轉換為NaN
(5)如果是對象,調用對象的valueOf()方法,再依照前面的規則轉換返回的值,如果轉換結果為NaN,調用對象的toString()方法,再依照前面的規則轉換
var s1="1", s2="12abc", s3="0xf", s4="", b=true, f="1.1", f1="1.1.2", n=null, u=undefined, o={valueOf:function(){ return -1; } }; console.log(+s1);//1 console.log(+s2);//NaN console.log(+s3);//15 console.log(+s4);//0 console.log(+b);//1 console.log(+f);//1.1 console.log(+f1);//NaN console.log(+n);//0 console.log(+u);//NaN console.log(+o);//-1
一元減號(-)放在數值前面,會改變數值的正負號。
在對非數值應用一元減操作符時,該操作符與一元加操作符遵循一樣的規則,最后再將得到的數值轉換為負數。
var s1="1", s2="12abc", s3="0xf", s4="", b=true, f="1.1", f1="1.1.2", n=null, u=undefined, o={valueOf:function(){ return -1; } }; console.log(-s1);//-1 console.log(-s2);//NaN console.log(-s3);//-15 console.log(-s4);//-0 console.log(-b);//-1 console.log(-f);//-1.1 console.log(-f1);//NaN console.log(-n);//-0 console.log(-u);//NaN console.log(-o);//1
3、加法
加法的操作規則如下:
(1)如果兩個操作數都是數值,執行常規的加法計算
- 如有一個操作數是NaN,結果是NaN
- Infinity+Infinity=Infinity
- -Infinity + -Infinity = -Infinity
- Infinity+ -Infinity= NaN
- 0+0=0
(2)如果有一個操作數是字符串:
- 如果兩個操作數都是字符串,將兩個字符串拼接
- 如果只有一個操作數是字符串,將另一個操作數轉換為字符串,然后再將兩個字符串拼接
(3)如果有一個操作數是對象、數值或布爾值,則調用它們的toString()方法取得相應的字符串值,在應用上述的字符串規則。對於undefined和null,則分別調用String()函數並取得字符串"undefined"和"null"
var r1=5+5; var r3="5"+"5"; var r2="5"+5; var r4=5+"5"; var r5=1+undefined; var r6="1"+undefined; var r7=1+null; var r8="1"+null; console.log(r1);//10 console.log(r2);//'55' console.log(r3);//'55' console.log(r4);//'55' console.log(r5);//NaN console.log(r6);//'1undefined' console.log(r7);//1 console.log(r8);//'1null'
4、減法
減法的操作規則如下:
(1)如果兩個操作數都是數值,執行常規的減法計算
- 如有一個操作數是NaN,結果是NaN
- Infinity-Infinity=NaN
- -Infinity - -Infinity = NaN
- Infinity- -Infinity= Infinity
- -Infinity- Infinity=-Infinity
- 0-0=0
(2)如果有一個操作數是字符串、布爾值、null或undefined,先在后台調用Number()函數將其轉換為數值,再計算,如果轉換結果是NaN,則結果是NaN
(3)如果有一個操作數是對象,則調用對象的valueOf()方法以取得表示該對象的數值,如果得到的值是NaN,則結果就是NaN。如果對象沒有valueOf()方法,則調用toString()方法
var r1=5-5; var r3="5"-"5"; var r2="5"-5; var r4=5-"5"; var r5=1-undefined; var r6="1"-undefined; var r7=1-null; var r8="1"-null;
var r9=2-""; console.log(r1);//0 console.log(r2);//0 console.log(r3);//0 console.log(r4);//0 console.log(r5);//NaN console.log(r6);//NaN console.log(r7);//1 console.log(r8);//1
console.log(r9);//2
巧用+/-規則轉換類型
var r1=1+""; var r2="1"-0; console.log(r1);//'1' 轉換成了字符串 console.log(r1);//1 轉換成了數字
5、乘性操作符
3個乘性操作符:乘法、除法、求模
如果參與乘性操作數不是數值,后台會先使用Number()轉型函數將其轉換為數值。
也就是說空字符串轉為0,true轉為1,flase轉為0
var r1=2*null; var r2=2*""; var r3=2*true; var r4=2*undefined; console.log(r1);//0 console.log(r2);//0 console.log(r3);//2 console.log(r4);//NaN
6、關系操作符
關系操作符:< > <= >=
當關系操作符的操作數有非數值時,要進行數據轉換,規則如下
(1)如兩個操作數都是數值,則執行數值比較
(2)如兩個操作數都是字符串,則比較兩個字符串對應的字符編碼值
(3)如一個操作數是數值,將另一個操作數轉換為數值,然后執行數值比較
(4)如果一個操作數是對象,則調用對象的valueOf()方法,再按照上面的規則,如沒有valueOf()方法,則調用toString()方法
(5)如一個操作數是布爾值,則先轉換為數值,再進行比較,true轉換為1,flase轉換為0
var r1="a">"B"; var r2=1>false; var r3=1>null; var r4=1>undefined; var r5=3>"23"; var r6="3">"23"; var r7="a">2; var r8=3>NaN; var r9=3<NaN; console.log(r1);//true B的字符編碼是66,a的字符編碼是97 console.log(r2);//true false-->0 console.log(r3);//true null-->0 console.log(r4);//false undefined-->NaN console.log(r5);//false console.log(r6);//true console.log(r7);//false a-->NaN console.log(r8);//false console.log(r9);//false
7、相等操作符
相等== 不相等 != 這兩個操作符都會先轉換操作數,然后再比較它們的相等性
遵循的規則:
(1)如果有一個操作數是布爾值,比較前先轉換為數值,false轉為0,true轉為1
(2)如果一個操作數是字符串,另一個操作數是數值,比較前先將字符串轉換為數值
(3)如果一個操作數是對象,另一個操作數不是,則調用對象的valueOf()方法,
(4)null==undefined
(5)在比較相等性前,不能將null和undefined轉換為其他任何值
(6)如果一個操作數是NaN,相等操作返回false,不相等操作返回true 。 NaN不等於NaN
(7)如果兩個操作數是對象,則比較它們是不是同一個對象,如果兩個操作數都指向同一個對象,則相等操作返回true
console.log(null==undefined);//true console.log(NaN==NaN);//false console.log(NaN!=NaN);//true console.log(false==0);//true console.log(true==1);//true console.log(undefined==0);//false
console.log(undefined==false);//false console.log(null==0);//false console.log(null==false);//false console.log("5"==5);//true console.log(new Object() == new Object());//false console.log([1, 2] == [1, 2]);//false
全等=== 不全等!== 操作規則
類型不同,返回false
類型相同
NaN ≠ NaN
new Object ≠ new Object
null === null
undefined === undefined
console.log("1"===1);//false console.log("1"+2===1+"2");//true console.log(1+"2" === "1" + new Number(2));//true 都轉成'12' console.log(1+true===false +2);//true console.log(1+null==undefined +1);//false 1+null-->1 undefiend+1-->NaN console.log("a"-"b"=="b"-"a");//false 前后都轉成NaN
二、語句中存在的隱式類型轉換
1、if語句
if(condition)statement1 else statement2
其中的condition(條件)可以是任意表達式,而且對這個表達式求值的結果不一定是布爾值。
ECMAScript會自動調用Boolean()轉換函數將這個表達式結果轉換為一個布爾值。
如果對condition求值的結果是true,則執行satement1,如果對condition求值的結果是false,則執行statement2
2、while語句
while(expression)statement
do{
statement
}while(expression)
同if語句
3、for in時的類型轉換
定義對象字面量時發生從標識符到字符串的隱式轉換。
var person = {'name':'jack',"age":20,school:'PKU'}; for(var a in person){ alert(a + ": " + typeof a); }
結果:
name: string
age: string
school: string
這里name,age分別加單/雙引號以強調其為String類型,school沒有加單/雙引號。我們遍歷下該對象的屬性,查看其類型。發現school也被隱式的轉換成了String類型。
數組的索引其實也是字符串類型。這着實令人驚嘆,但事實的確如此。如
var ary = [1,3,5,7]; for(var a in ary){ alert(a + ": " + typeof a); }
結果:
0: string
1: string
2: string
3: string
三、alert時存在的隱式類型轉換
String.prototype.fn = function(){return this}; var a = 'hello'; alert(typeof a.fn()); //-->object alert(a.fn()); //-->hello
給String原型上添加了個fn方法,該方法返回this,我們知道this可以理解成當前類的實例對象,既然是對象那么typeof a.fn()自然返回是object了。
關鍵是最后的alert(a.fn()),a.fn()返回的明明是對象,但卻隱式的轉換成了字符串“hello”顯示。
同樣的情況發生在數字類型上,如
Number.prototype.fn = function(){return this}; var a = 10; alert(typeof a.fn());//-->object alert(a.fn()); //-->10
a.fn()返回的是對象類型,但在alert(a.fn())時會隱式的將其轉換成數字。