進擊的 JavaScript(一) 之 類型轉換

提及 js 類型轉換,都是頭疼吧,暈暈的,可是不行啊,這東西很重要滴!

基礎知識

JavaScript的數據類型分爲六種,分別爲null, undefined, boolean, string, number, object。數組

object是引用類型,包含數組,其它的五種是基本類型或者是原始類型(原始值)。bash

咱們能夠用typeof方法打印來某個是屬於哪一個類型的。不一樣類型的變量比較或者運算,要先轉類型,叫作類型轉換。函數

注意,typeof null 返回 "object",它是一個特殊的對象值,含義是「非對象」。實際上,咱們一般認爲null是自有類型的惟一成員。ui



1、顯式轉換

parseInt()和parseFloat() 字符串轉數字this

js提供了parseInt()parseFloat()兩個轉換函數。前者把值轉換成整數,後者把值轉換成浮點數。只有對String類型調用這些方法,這兩個函數才能正確運行;對其餘類型返回的都是NaN(Not a Number)spa

parseInt()prototype

parseInt("1234blue");   //1234 
parseInt("0xA");   //10 
parseInt("22.5");   //22 
parseInt("blue");   //NaN
複製代碼

parseInt()方法還有第二個參數,能夠把二進制、八進制、十六進制或其餘任何進制的字符串轉換成整數。因此要解析十六進制的值,需以下調用parseInt()方法:code

parseInt("AF",   16);   //175 
複製代碼

固然,對二進制、八進制,甚至十進制(默認模式),均可以這樣調用parseInt()方法:cdn

parseInt("10",   2);    //2 
parseInt("66",   8);    //54 
parseInt("10",   10);   //10 
複製代碼

parseFloat字符串轉浮點數字,沒有第二個參數。 下面是使用parseFloat()方法的示例:對象

parseFloat("1234blue");  //1234.0 
parseFloat("0xA");       //NaN 
parseFloat("22.5");      //22.5 
parseFloat("22.34.5");   //22.34 
parseFloat("0908");      //908 
parseFloat("blue");      //NaN
複製代碼

toFixed() 數字轉成字符串

根據參數保留小數點後幾位 會四捨五入,若是無參,默認爲0; 例:

(66.55).toFixed();    //"67"
(66.64).toFixed(1);   //"66.6"
複製代碼

toExponenttial() 數字轉成字符串

根據參數保留小數點後幾位 指數形式 會四捨五入 這個我不就不舉例了,感興趣的,本身百度下把。

Number對象的 toString() 方法, 數字轉字符串

根據2 8 16 (範圍2 - 36)分別轉爲二進制 八進制 十六進制字符串,, 不帶參,就默認爲10, 轉十進制。 例:

(6).toString(2);     //"110"
(66).toString(8);    //"102"
(66).toString(16);   //"42"
複製代碼

下面三個構造函數,當沒有使用 new 時,表示類型轉換函數,使用new 時,表示轉對象(建立一個對應對象),即轉換獲得的值 建立一個對應的對象。

Boolean()

它會把 「真值」 轉爲 true , 「假值」 轉爲 false

Boolean()方法的示例:

Boolean("");               //false   「假值」
Boolean("zdx");            //true    「真值」 
Boolean(66);               //true    「真值」 
Boolean(null);             //false   「假值」
Boolean(0);                //false   「假值」
Boolean(new Object());     //true    「真值」 
複製代碼

Number()

有如下規律:

  1. falsenull""[],轉爲0
  2. true , 轉1
  3. 數字轉數字
  4. 全是數字的字符串轉數字
  5. **數組內全是數字(不能有逗號)**轉數字
  6. **數組內字符串全是數字(不能有逗號)**轉數字
  7. 其餘都是 NaN

大栗子:

Number(false);            //0 
Number(null);             //0 
Number("");               //0 
Number([]);               //0
Number(true);             //1 
Number("66");             //66 
Number("66f");            //NaN 
Number(new Object());     //NaN 
Number([66]);             //66
Number(["66"]);           //66       
Number([6,6]);            //NaN
Number(["6f6"]);          //NaN
複製代碼

String()

String()可把任何值轉換成字符串。它就是調用傳進參數toString()方法。使用String()轉換成字符串和調用toString()方法的惟一不一樣之處在於,對nullundefined值轉換能夠生成字符串而不引 發錯誤:

String()方法的示例:

String(null);            //"null" 

var   null   =   null; 
null.toString();        //報錯
複製代碼

Object()

這個函數,使用 和 不使用 new 是同樣的。

它會把原始值,根據它的類型,使用對應的構造函數,建立一個對象。nullundefined 和建立一個空對象。

Object(66);           //數字對象,等於  new Number(66)
Object("66");         //字符串對象,等於  new String("666")
Object(true);         //布爾對象, 等於  new Boolean(true)
Object(null);         //空對象,等於 new Object()
Object(undefined);    //空對象,等於 new Object()
複製代碼


2、隱式轉換

(一)、全部類型 轉爲 布爾

JavaScript 的基礎類型中 有布爾類型,這個類型的值,只有兩個值---- true 和 false

任意的JavaScript 的值均可以轉換爲布爾值。但只有下面這六個值會轉爲false:

""
0
-0
null
undefined
NaN
複製代碼

其餘全部值,包括全部對象(數組)都會轉換爲 true。布爾值 false,和上面6個能轉爲false 的值,咱們通常稱爲「假值」,其餘值稱爲「真值」。(「真值」等價true,「假值」等價false)

注意!!!在JavaScript 中 ,任何但願使用布爾值的地方,都會將操做數看成 「真假」 或 「假值」 對待(即把「真值」當true,「假值」當false)。這句話你如今不懂沒事,看完下面的,或許你就懂了,哈哈。

(二)、原始值 轉爲 數字

字符串 轉 數字

當字符串裏,全爲數字時,轉數字,其餘都爲NaN。空字符串就轉0

+ "666";    //666
+ "66f";    //NaN
+ "";       //0
複製代碼

布爾轉數字

這個比較簡單了。 true 轉 1;false 轉 0;

+ true;   //1
+ false;  //
複製代碼

null 轉數字

null 轉 0。

+ null;        //0
複製代碼

undefined 和 NaN 轉數字

undefined 和 NaN 都轉 NaN。

+ undefined;   //NaN
+ NaN;         //NaN
複製代碼


(三)、原始值 轉爲 字符串

這個也比較簡單,原始值 到 字符串,就原封不動的轉(加個雙引號)。

"zdx" + true;    //"zdxtrue"
複製代碼


(四)、 引用類型( 對象 )轉爲 原始值

對象 轉 布爾

對象 轉 布爾 都爲 true;等同於 Boolean()

![];     //false    這裏取反了,注意,取反會把操做值轉布爾
!{};     //false
複製代碼

對象 轉 數字

對象 轉 數字 ,首先調用 valueOf(),若是返回的是原始值,再轉數字(須要的話),並返回;不然調用 toString(), 若是返回的是原始值,再轉數字,並返回;不然 拋出一個類型錯誤。

+ [];    //0
//[].valueOf();   返回數組自己[],因此調用 [].toString(); 返回 空字符串"",""再轉數字 0;
+ (new Date());   //1526008864094
//調用  (new Date()).valueOf(); 返回1526008864094
複製代碼

對象 轉 字符串

對象 轉 字符串 ,跟轉數字的規則同樣。只不過是轉字符串。 首先調用 valueOf(),若是返回的是原始值,再轉字符串(須要的話),並返回;不然調用 toString(), 若是返回的是原始值,再轉字符串,並返回;不然 拋出一個類型錯誤。

"66" + [];    //"66"
"66" + {};    //"66[object Object]"
複製代碼

總結:對象對原始值,除了布爾類型,其餘都是先調用valueOf,而後根據須要調用toString。

想知道,js 每一個內置對象的valueOf()toString()方法,能夠翻到最下面,附錄

3、隱式轉換 發生的地方

隱式轉換一般發生在表達式 和 運算符 。

(1)加減乘除:

加號 +

二元運算符用法(兩個操做數)

能夠對數字作加法, 也能夠作字符串鏈接操做。 當兩個操做數 都是 數字 或 字符串時,計算是顯然的。其餘狀況下,有以下規則

  1. 對象轉原始值,除了Date 對象 直接調用toString,其餘對象,調用自身的valueOf 方法,但有的對象自身沒有valueOf,或者獲得的不是原始值,此時調用toString
  2. 第一步轉換後,若是其中一個是字符串的話,另外一個操做數也轉字符串,進行字符串鏈接。
  3. 不然,都轉爲數字(或者NaN),進行加法。

栗子來了:

1 + new Date();     //"1Fri May 11 2018 14:20:50 GMT+0800 (中國標準時間)"

1 + new Number(2);    //3  (new Number).valueOf(); 返回2, 和1 作加法

"66" + 6;       //666    6 轉 "6"

1 + {};         //"1[object Object]"   ({}).toString()

true + false;   //1    都轉數字

1 + null;       //1    null 轉數字

1 + undefined;  //NaN   undefined 轉 NaN
複製代碼

實際代碼中,常常這樣

var x = 66;
x + "";     //"66"    等價於 String(x)
複製代碼

注意:兩點!

  1. 不要把對象字面量形式的值放在前面。
  2. 從左到右的進行 + 運算。

//對象字面量形式放在前面的結果比較複雜,不建議使用。(下面的結果不是惟一的)
{} + 1;     //1
{} + "1";   //1
{} + {};    //"[object Object][object Object]"
{x:1} + {};  //NaN

//從左到右,逐個作 + 運算
1 + 2 + "";    //"3"
1 + "" + 2;    //"12"
複製代碼
一元運算符用法(一個操做數)

把操做數轉換爲 數字(或者NaN),並返回它。

+ "666";       //666   等價於 Number("666")
+ undefined;   //NaN
複製代碼

減號 -

都是轉數字。

- "666";    //-666
- "66f";    //NaN
1 - null;   //1
複製代碼

乘號 *

都是轉數字

1 * "666";     //666
1 * null;      //0
複製代碼

除號 /

都是轉數字

"666" / 1;     //666
1 / true;      //1
複製代碼


(2)比較運算符 (> < >= <=)

比較運算符用來檢測兩個操做數(數字或字符串)的大小關係(數值大小或者字符串首個字符的16位Unicode的大小 )。

比較運算符的操做數多是任意類型。但只有數字和字符串才能比較。所以,它會把別的操做數進行類型轉換,規則以下:

  1. 對象轉原始值,若是valueOf()返回原始值,直接比較,不然,調用toString()進行轉換。
  2. 轉原始值後,若是兩個操做數都是字符串,那麼將按字符串首個字符的16位Unicode的大小 進行比較。
  3. 不然都轉數字比較。Infinity比任何數字都大(除了自身),-Infinity 相反。若是一個操做數是NaN(或轉NaN),結果返回false。
11 < 3;

"11" < "3";   //true    "11" 首個字符串 "1" 的16位Unicode 值比 "3"的16位Unicode 小

//"11".charCodeAt(0).toString(16) 31

//"3".charCodeAt(0).toString(16)  33

"11" < 3;     //false   "11" 轉 11,false

{} < 3;       //false   {}轉原始值字符串,字符串轉NaN, false

null < 3;     //true    null 轉數字
複製代碼

最後要注意的是,<= 和 >= 比較時,並不根據 == 和 === 的規則(在下方)比較,它就僅僅表示 數值 或 字符串 之間的比較。

null >= undefined    //false
複製代碼


(3)in運算符

把左操做數轉 字符串

in 運算符但願它的左操做數是一個字符串或能夠轉換爲字符串,右操做數是一個對象。若是,右側的對象擁有一個名爲左側操做數值的屬性名,那麼表達式返回true。

var point = { x:1, y:2};
"x" in point;    //true  point 有一個 x 的屬性名

var arr = [a,b,c];
1 in arr;        //true   數組的索引就至關於 屬性名
複製代碼


(4)! 和 !!

! 它會把操做值 轉爲 布爾值(「真值」爲true,「假值」爲false),對布爾值求反。(結果只有true,false)

例:

console.log(!"");           //true
console.log(!0);            //true
console.log(!-0);           //true
console.log(!null);         //true
console.log(!undefined);    //true
console.log(!NaN);          //true
console.log(!false);        //true
複製代碼

!! 獲得操做值 等價的 布爾值(「真值」爲true,「假值」爲false) 等同於 Boolean(),常常稱!! 爲強制轉換。 例:

console.log(!!"");           //false
console.log(!!0);            //false
console.log(!!-0);           //false
console.log(!!null);         //false
console.log(!!undefined);    //false
console.log(!!NaN);          //false
console.log(!!false);        //false
複製代碼

總結:「假值」 取反都是true, 「真值」取反爲false;「假值」 強制轉換 都是 false, 「真值」強制轉換爲 true



(5)== 和 ===

都知道 == 是判斷 左右值 是否想等的。而 === 不只判斷 右右值是否想等,還要判斷,類型是否同樣。結果返回布爾值

== 的用法 NaN是JavaScript中惟一一個不等於任何值的(包括它本身)。(NaN == NaN) // false

通常對NaN的判斷:

function isNaN(num){
    return typeof num === "number" && num !== num;
}
複製代碼

注意,跟js 自帶的 isNaN 方法 不同。

左右兩邊類型相同

一、原始值的比較

它們的比較,就是值的直接比較。 好比:

console.log(null == null);               //true
console.log(undefined == undefined);     //true
console.log(666 == 666);                 //true
console.log(666 == 1);                   //false
console.log("周大俠啊" == "周大俠啊");      //true
console.log("周大俠啊" == "大佬");         //false
console.log(true == true);               //true
console.log(true == false);              //false
複製代碼

二、對象的比較

對象和原始值不一樣,首先,它們是可變的-----它們的值是可修改的:

var o = { x:1 };   //定義一個對象
o.x = 2;           //修改x的值

var a = [1,2,3];   //數組也是可修改的
a[0] = 0;          //修改數組第一個元素
複製代碼

**對象的比較並不是值的比較,而是引用(內存地址)的比較。 **

var o1 = { x:1 };
var o2 = { x:1 };
console.log( o1 == o2 );    //false
//即便 對像的屬性,值徹底相同, 也不相等

var o3 = o1;
console.log( o1 == o3 );    //true
//o3 和  o1 引用的是同一對象。(即指向的是同一塊儲存地址)

//數組同上
複製代碼

左右兩邊類型不一樣

若是 == 兩邊的 類型不一樣,則比較時,有如下兩個個規則:

  1. undefined等於null
  2. 其餘都轉數字比較

對象經過valueOf 或 toString 轉換爲原始值,原始值在對應轉數字。

總結:左右兩邊類型不一樣, == 在比較時,除了(null == undefined),NaN,其餘都是轉爲數字比較, 歷來不會轉爲布爾值!

舉個大栗子:

//1. undefined等於null
undefined == null; //ture

//2. 字符串和數字比較時,字符串轉數字
"0" == 0;  //true
"f" == 0;  //false
//字符串轉數字時,只有在字符串是純數字時,轉對應數字,其餘都轉爲 NaN。

// 3. 字符串和布爾比較時,都轉爲數字
"0" == false;   //true
"1" == true;    //true

//4. 數字和布爾比較時,布爾轉數字
1 == true;    //true
0 == false;   //true
//true 轉 1, false 轉0;

//5.對象 和 字符串,數字比較, 都轉數字。
new String("66") == "66";      //true
new String("zdx") == "zdx";    //false
new String("66") == 66;        //true
複製代碼

=== 的用法

這個比較,首先,看兩邊類型是否一致,不一致, 直接false,一致的話,再根據 == 的使用規則, 進行比較。

(6)!= 和 !==

這兩個 運算 跟 取反(!) 操做是 不同 的!,注意區分。

這兩個運算,是在 == 和 === 比較事後的結果,進行取反(就是對 true 和 false 取反,由於,== 和 === 的返回值 只有 true 和 false)。

簡單栗子:

"0" == 0;  //true
"f" === 0;  //false

"0" != 0;  //false
"f" !== 0;  //true
複製代碼


(7)&&、||

&& 邏輯與

  1. 若是兩側都是布爾值, 進行布爾(AND)運算。
  2. 不然它會先計算左側表達式,若是爲 「假值」,返回這個值,若是是「真值」,計算右側表達式,並返回計算結果。

看:

true && false;       //false
1 && 2;              //2
null && 2;           //null
1-1 && 2;            //0
2-1 && 0;            //0
複製代碼

因此,有時候就會這樣寫代碼:

if( a==b ) start();
a == b && start();    //效果同上
複製代碼

|| 邏輯或

它跟 && 的行爲是同樣的,只是它的作的是布爾(OR)運算,返回的狀況相反

  1. 若是兩側都是布爾值, 進行布爾(OR)運算。
  2. 不然它會先計算左側表達式,若是爲 「真值」,返回這個值,若是是「假值」,計算右側表達式,並返回計算結果。
true || false;       //true
1 || 2;              //1
null || 2;           //2
1-1 || 2;            //2
2-1 || 0;            //1
複製代碼


(8)if 語句

它會計算操做數的值,「真值」 表現爲true , 「假值」 表現爲false。



附錄

1、Object

一、valueOf 返回對象自己。

({x:1,y:2}).valueOf();    //{x: 1, y: 2},返回的是對象!
複製代碼

二、toString 返回 "[object type]",其中type是對象的類型。

//這裏使用函數的call方法,指定 this的指向
var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]

toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
複製代碼


2、Boolean

一、valueOf 返回布爾值。

(true).valueOf();    //true , 返回的是原始值,Boolean類型
複製代碼

二、toString 返回該對象的字符串形式。

(true).toString();     //"true",返回的是原始值,string類型
複製代碼


3、Date

一、valueOf 返回存儲的時間是從 1970 年 1 月 1 日午夜開始計的毫秒數 UTC。

(new Date()).valueOf();    //1525943413141  一串數字
複製代碼

二、toString 返回一個美式英語日期格式的字符串.

(new Date()).toString();    //"Fri May 11 2018 10:26:16 GMT+0800 (中國標準時間)"  原始值,string類型
複製代碼


4、Number

一、valueOf 返回數字值。

(66).valueOf();    //66   返回的是原始值,Number類型
複製代碼

二、toString 返回的是原始值,String類型 根據2 8 16 (範圍2 - 36)分別轉爲二進制 八進制 十六進制字符串,, 不帶參,就默認爲10, 轉十進制。 例:

(66).toString(2);    //"1000010"
(66).toString(8);    //"102"
(66).toString(16);   //"42"
複製代碼


5、String

一、valueOf 返回字符串值。

("666").valueOf();    //"666"   返回的是原始值,String類型
("zdx").valueOf();    //"zdx"   返回的是原始值,String類型
複製代碼

二、toString 和valueOf 效果同樣,返回字符串值。

("666").toString();    //"666"   返回的是原始值,String類型
("zdx").toString();    //"zdx"   返回的是原始值,String類型
複製代碼



6、Array

一、valueOf 自身沒有該方法,繼承Object.prototype.valueOf。返回的是數組對象!

([1,2,3]).valueOf();     //(3) [1, 2, 3],
複製代碼

二、toString 返回表示該數組的字符串,跟使用 Array.prototype.join(","),效果等同

([1,2,3]).toString();     //"1,2,3",    原始值,string類型
([1,2,3]).join(",");      //"1,2,3",
複製代碼


7、Function

一、valueOf 自身沒有該方法,繼承Object.prototype.valueOf。 返回的是函數,使用typeof 返回 function,但注意原始值沒有function類型

function a(){ console.log(666) };
a.valueOf();    //ƒ a(){ console.log(666) };  
複製代碼

二、toString 返回當前函數源代碼的字符串。

function a(){ console.log(666) };
a.toString();    //"function a(){ console.log(666) }";返回的是原始值,string類型
複製代碼


8、Error

一、valueOf 自身沒有該方法,繼承Object.prototype.valueOf。 返回Error 對象自己

(new Error("fatal error")).valueOf();   //Error: fatal error
複製代碼

二、toString 返回一個指定的錯誤對象(Error object)的字符串表示。

var e = new Error("fatal error");
print(e.toString()); // "Error: fatal error"
複製代碼


9、Math

它是全局對象, 不屬於函數。 一、valueOf 自身沒有該方法,繼承Object.prototype.valueOf。

Math.valueOf();     //返回Math 對象自己
複製代碼

二、toString 自身沒有該方法,繼承Object.prototype.toString。

Math.toString();    //"[object Math]"
複製代碼

這裏寫圖片描述
相關文章
相關標籤/搜索