JS型別轉換之隱式轉換
阿新 • • 發佈:2020-09-15
Boolean()將其他資料型別轉成布林值
- 0、-0、空字串""、null、undefined、NaN、false、document.all()這8個轉布林值為false,其他的都為true。
Boolean(0) // false Boolean(-0) // false Boolean('') // false Boolean(null) // false Boolean(undefined) // false Boolean(NaN) // false Boolean(document.all()) // false Boolean(' ') // true Boolean('-1') // true Boolean([]) // true Boolean({}) // true Boolean(function(){}) // true Boolean(Symbol()) // true
Number()將其他資料型別轉成數值
- null轉為0
- undefined轉為NaN
- true轉為1,false轉為0
- 引用型別先轉成字串然後再轉成數值,字串必須是數字字串才能成功轉成相應的數值,否則都為NaN。空字串""以及只有空格的字串" "轉為0
Number(null) // 0 Number(undefined) // NaN Number(true) // 1 Number(false) // 0 Number('') // 0 Number(' ') // 0 Number([1]) // 1 [1].toString()返回'1' Number([1,2]) // NaN [1,2].toString()返回'1,2',轉數值為NaN Number({}) // NaN ({}).toString()返回'[object Object]',轉數值為NaN
注:事實上引用型別轉數值的過程中會自動呼叫物件的 valueOf() 和 toString()。
- 先呼叫 valueOf(),返回值是基本型別的話,即可轉數值。
- 如果 valueOf() 的返回值不可直接轉數值的話,再自動呼叫物件的toString(),然後再將得到的字串轉數值。
var obj = { valueOf: function(){ console.log('valueOf方法被呼叫了'); return '666'; }, toString: function(){ console.log('toString方法被呼叫了'); return '2333'; } } Number(obj) // valueOf方法被呼叫了 // 666 var obj = { valueOf: function(){ console.log('valueOf方法被呼叫了'); return {}; }, toString: function(){ console.log('toString方法被呼叫了'); return '2333'; } } Number(obj) // valueOf方法被呼叫了 // toString方法被呼叫了 // 2333
valueOf() 返回物件的原始值
MDN文件
valueOf方法一般都會被 JavaScript 自動呼叫,比如發生隱形轉換時。
String()將其他資料型別轉成字串
String() 和 toString() 效果基本相同,唯一區別就是toString()無法轉換null和undefined
var a;
var b=null;
a.toString(); //Uncaught TypeError: Cannot read property 'toString' of undefined
b.toString(); //Uncaught TypeError: Cannot read property 'toString' of null
String(a); //"undefined"
String(b); //"null"
注:引用型別隱形轉換字串時還是遵循先 valueOf() 再 toString(),而不是直接 String()
var obj = {
valueOf: function(){
console.log('valueOf方法被呼叫了');
return '666';
},
toString: function(){
console.log('toString方法被呼叫了');
return '2333';
}
}
'00-' + obj
// valueOf方法被呼叫了
// '00-666'
'00-' + String(obj)
// toString方法被呼叫了
// '00-2333'
隱式型別轉換場景
+ (字串連線符/算術運算子)
+兩邊有一邊是字串的話,此時+為字串連線符,其他情況則為算術運算子。
- 字串連線符:將其他資料型別轉成字串,然後進行拼接。
- 算術運算子:將其他資料型別用Number()轉成數字,然後做加法運算。
1 + '-haha' // '1-haha'
1 + true // 2 Number(true)為1
1 + null // 1 Number(null)為0
1 + undefined // NaN Number(undefined)為NaN
1 + {} // '1[object Object]' {}轉數字的過程中先轉成了字串,然後就變成了字串拼接
1 + [1,2,3] // '11,2,3' 原因同上
[] + {} // '[object Object]' 原因同上
{} + [] // 0 大括號{}在前面被認為是程式碼塊,所以相當於是 +[]
>、<、>=、<= (關係運算符)
會把其他資料型別轉成number數字型別來進行比較,但有些具體情況比較特殊。
- >、<、>=、<= 的兩邊都是字串的話,比較的是字元的Unicode編碼。
// 一般情況下 Number('2') > 10 false
'2' > 10 // false
// 兩邊都是字串 '2'.charCodeAt() > '10'.charCodeAt() true
'2' > '10' // true
// 多個字元依次比較 'a'.charCodeAt() > 'b'.charCodeAt false
'aac' > 'abc' // false
<br/>
## ==(關係運算符)
* 型別相同,不發生型別轉換。如果都是引用型別,則比較的是引用地址
* 型別不同,則轉成number數字型別再進行比較
* NaN不與任何值相等,包括NaN自己
```javascript
[1] == [1] // false
{} == {} // false
9 == [9] // true
NaN == NaN // false
特殊情況:如果資料型別是 null 和 undefined ,結果固定,無規則。
null == null // true
undefined == undefined // true
undefined == null // true
!(邏輯非)
- 邏輯非,將其他資料型別轉成布林值
- 邏輯非!優先順序高於關係運算符
// 先算邏輯非,Boolean([])為true => ![]為false => Number(false)為0
![] == 0 // true
// 先算邏輯非,![]為false => Number(false)為0,[].toString()為'' => Number('')為0
[] == ![] // true
// 先算邏輯非,({}).toString()為'[object Object]' => Boolean('[object Object]') => !{}為false,Number('[object Object]')為NaN
{} == !{} // false
經典面試題
var a = ???
if(a == 1 && a == 2 && a == 3){
console.log('少林功夫好嘢');
}
// 如何完善a,使其正確打印出'少林功夫好嘢'
// 分析
// ==會發生隱式轉換
// ==兩邊資料型別不同則轉成Number數字型別來進行比較
// a比較3次3次不同,a只能是引用型別,引用型別轉Number數字型別過程先後自動呼叫valueOf()和toString()
// 經過以上幾步分析,豁然開朗
var a = {
b: 1,
valueOf: function(){
return this.b++;
}
}
if(a == 1 && a == 2 && a == 3){
console.log('少林功夫好嘢')
}
// '少林功夫好嘢'