JavaScript數據類型隱式類型轉換的種類

進入正題之前,首先介紹下對象的valueOf()和toString()方法,因爲很多隱式轉換的場景會用到valueOf和toString方法。

每個對象都有這兩個方法。在控制檯輸出Object.prototype,其中就有valueOf和toString方法,而Object.prototype是所有對象原型鏈頂層原型,所有對象都會繼承該原型的方法,故任何對象都會有valueOf和toString方法。js的常見內置對象有:Date, Array, Math, Number, Boolean, String, Array, RegExp, Function。

valueOf方法:

(1)Number、Boolean、String這三種構造函數生成的基礎值的對象形式,通過valueOf轉換後會變成相應的原始值。

var num = new Number('123');
num.valueOf(); // 123

var str = new String('12df');
str.valueOf(); // '12df'

var bool = new Boolean('fd');
bool.valueOf(); // true

(2)Date這種特殊的對象,其原型Date.prototype上內置的valueOf函數將日期轉換爲日期的毫秒的形式的數值。

var a = new Date(); a.valueOf(); // 1515143895500

(3)除此之外返回的都爲this,即對象本身

var a = new Array();

a.valueOf() === a; // true

var b = new Object({});

b.valueOf() === b; // true

toString()方法:

(1)Number、Boolean、String、Array、Date、RegExp、Function這幾種構造函數生成的對象,通過toString轉換後會變成相

應的字符串的形式,因爲這些構造函數上封裝了自己的toString方法。

Number.prototype.hasOwnProperty('toString'); // true
Boolean.prototype.hasOwnProperty('toString'); // true
String.prototype.hasOwnProperty('toString'); // true
Array.prototype.hasOwnProperty('toString'); // true
Date.prototype.hasOwnProperty('toString'); // true
RegExp.prototype.hasOwnProperty('toString'); // true
Function.prototype.hasOwnProperty('toString'); // true

var num = new Number('123sd');
num.toString(); // 'NaN'

var str = new String('12df');
str.toString(); // '12df'

var bool = new Boolean('fd');
bool.toString(); // 'true'

var arr = new Array(1,2);
arr.toString(); // '1,2'

var d = new Date();
d.toString(); // "Wed Oct 11 2017 08:00:00 GMT+0800 (中國標準時間)"

var func = function () {}
func.toString(); // "function () {}"

(2)除以上這些對象及其實例化對象之外,其他對象返回的都是該對象的類型,都是繼承的Object.prototype.toString方法。

var obj = new Object({});
obj.toString(); // "[object Object]"

Math.toString(); // "[object Math]"

接下來就是一些常見的隱式轉換的場景:

1、加法操作符(+)

  • 若有一個操作數爲NaN,結果爲NaN
  • 若有一個操作數爲字符串,則將另一個數轉換爲字符串然後拼接
  • 若有一個操作數爲對象,則調用對象的toString方法再執行上一步

// num: 數值操作數 str: 字符串 obj: 對象

num + 非字符串操作數(NaN/undefined/null/false/true) = num + Number(非字符串操作數)

num + str = 'numstr';  // 1 + 2 + '3' = '33'

str + NaN = 'strNaN';  // '1' + NaN = '1NaN'

str + null = 'strnull';  // '1' + null = '1null'

str + true = 'strture';

obj + num = obj.toString() + num;  // Math + 123 = '[object Math]123'

obj + str = obj.toString() + str; // Math + '123' = '[object Math]123'

 

2、減法操作符(-)

  • 若一個操作數爲字符串、null、undefined、布爾值,就調用Number()將其轉換爲數值再運算
  • 若一個操作數爲對象則調用該對象valueOf(),沒有valueOf()則調用toString()

1 - '2' = -1;

1 - '123a' = NaN;  // 1 - Numer('123a')

1 - Math = NaN;  // 1 - Math.valueOf()

1 - true = 0;

 

3、乘/除法操作符(*、/)

  • 若有一個操作數爲NaN,則結果爲NaN
  • 若其中一個操作數不爲數字,則調用Number()將其轉換爲數值

2 * '5'; // 10

2 * '5a'; // 2 * Number('5a') -------->

2 * NaN ------------> NaN

 

4、布爾操作符(!、&&、||)

  • 當使用 條件判斷語句(if...else) 以及 布爾操作符(!、&&、||) 時,會調用Boolean()進行隱式類型轉換
  • 轉換爲false的有:0, null, undefined, NaN, '', false,其餘都爲true([], {}爲true)

![]; // !Boolean([]); ------------> false

!2; // false

!null; // !Boolean(null); ------------> true

!undefined; // true

!0; // true

if([]) consolo.log('true'); // if(Boolean([])) ... -----------> true

 

5、關係操作符(>、<、>=、<=)

  • 與NaN比較都會返回false
  • 若兩個操作數都爲字符串,則比較字符串的編碼值
  • 若有一個操作數爲數值,則對另一個操作數用Number()轉換
  • 若有一個操作數爲對象,則調用該對象valueOf(),沒有valueOf()則調用toString()

4 > '2'; // true

4 > '2a'; // false

4 > Math; // false

4 > true; // true 

'ab' > 'a' // true

 

6、相等操作符(==、!=)

  • 字符串、布爾類型和數值比較,現將前者用Number()轉換爲數值
  • 若一個操作數是對象另一個不是,則調用該對象valueOf(),沒有valueOf()則調用toString()
  • 若兩個操作數都是對象,則比較它們是不是同一個對象(地址是否相同)
  • null和undefined是相等的
  • null和undefined不會轉換成任何值
  • 任何數都不等於NaN,包括NaN自己

 

 //特例:

 

NaN == NaN//false //NaN是唯一不等於自身的

// true

'123' == 123 

[123] == 123 

true == '1'

1 == true 

'1' == true 

'123' == new String(123);

null == undefined;

// false

2 == true 

'2' == true 

null == 0;

new String(123) == new String(123);

 

7、全等操作符(===、!==)

  • 全等操作符不會轉換操作數

123 === '123'; // false

null === undefined; // false

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章