[深刻06] 隱式轉換 和 運算符

導航

[深刻01] 執行上下文
[深刻02] 原型鏈
[深刻03] 繼承
[深刻04] 事件循環
[深刻05] 柯里化 偏函數 函數記憶
[深刻06] 隱式轉換 和 運算符
[深刻07] 瀏覽器緩存機制(http緩存機制)
[深刻08] 前端安全
[深刻09] 深淺拷貝
[深刻10] Debounce Throttle
[深刻11] 前端路由
[深刻12] 前端模塊化
[深刻13] 觀察者模式 發佈訂閱模式 雙向數據綁定
[深刻14] canvas
[深刻15] webSocket
[深刻16] webpack
[深刻17] http 和 https
[深刻18] CSS-interview
[react] Hooks前端

[部署01] Nginx
[部署02] Docker 部署vue項目
[部署03] gitlab-CIvue

[源碼-webpack01-前置知識] AST抽象語法樹
[源碼-webpack02-前置知識] Tapable
[源碼-webpack03] 手寫webpack - compiler簡單編譯流程react

強制轉換

  • Number,String,Boolean
  • js是動態類型的語言,變量沒有類型限制,能夠隨意賦予任意值
  • 雖然變量的數據類型不肯定,但各類(運算符)對變量的(數據類型)是有限制的

Number()強制轉換

  • 參數:兩種狀況,參數是原始類型的值,參數是對象
  • 結果:將任意的數據類型轉換成數值,數值 或者 NaN
  • Number的轉換要比parseInt嚴格,只要一個字符不能轉換成數值,整個字符串就會被轉換成NaN
  • Null => 0
  • undefined => NaN

Number參數:原始類型的值

Number() 參數是原始類型的值

1. 爲0的狀況
Number(false)
Number('')
Number(Null)

2. 爲NaN的狀況
Number(undefined)
Number('123abc') // 不能轉成數值的字符串

// Number比parseInt嚴格的多,只要一個字符不能轉換成數值,整個字符串將被轉換成NaN
// parseInt('123abc') // 123
// Number('123abc') // NaN

3. 爲1的狀況 
Number(true)
複製代碼

Number參數:對象

  • Number() 的參數類型是對象時,只要不是單個數值的數組,都會轉成NaN
Number() 參數是對象

Number([7]) // 7
Number([1,2]) // NaN
Number({a:1}) // NaN
複製代碼

Number具體的轉換規則

Number具體的轉換規則

1. 調用對象自身的 valueOf 方法
- 若是返回原始類型的值,則直接使用Number函數,不在進行後續步驟
- 若是返回對象,則繼續判斷

2. valueOf返回對象,則調用對象自身的 toString 方法
- 若是返回原始類型的值,則直接使用Number函數,不在進行後續步驟
- 若是返回對象,則繼續判斷

3. toString返回對象,則報錯


總結: 
valueOf => 對象 => toStirng => 對象 => 報錯
以上步驟,若是返回原始類型的值,就調用Number(),並終止後續步驟
// valueOf : 對象的valueOf 返回對象自己
// toString : 對象的toString 返回對象的字符串形式
// valueOf和toString能夠自定義
複製代碼

String()強制轉換

  • 將任意類型的值轉換成字符串
  • 參數:原始類型的值 或 對象
  • 結果:字符串
String()強制類型轉換

1. 參數:原始類型的值
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"

2. 參數:對象
- 參數是對象,返回類型字符串
- 參數是數組,返回數組的字符串形式
String({name: 'woow_wu7'}) // 參數是對象,返回類型字符串  ==> '[object Object]'
String([1,2]) // 參數是數組,返回數組的字符串形式,==> '1,2'


3. 具體的轉換規則
1. 調用對象的 toStirng 方法
- 若是返回原始類型的值,則使用String()方法轉換
- 若是返回的是對象,繼續如下步驟
2. 調用對象的 valueOf 方法
- 若是返回原始類型的值,則使用String()方法轉換
- 若是返回對象,繼續如下步驟
3. valueOf返回對象,則報錯


總結:
先調用 toString() -> 對象 -> valueOf() -> 對象 -> 報錯
以上步驟,若是返回原始類型的值,則調用 String(),並停止後續步驟
// String參數是對象時
// 參數是對象:返回類型字符串
// 參數是數字:返回數組的字符串形式
複製代碼

Boolean()強制轉換

  • 將任意類型的值轉成布爾值
Boolean類型轉換

除了如下6個值是false,其餘都爲true
Boolean(+0) // false
Boolean(-0) // false
Boolean('') // false
Boolean(null) // false 
Boolean(undefined) // false
Boolean(NaN) // false
複製代碼

自動轉換

  • 自動轉換髮生的時機
    • 不一樣類型的數據相互運算
    • 對非布爾類型的數據求布爾值
    • 對非數值類型的值使用一元運算符
  • 自動轉換的規則
    • 預期什麼類型的值,就調用該類型的轉換函數

自動轉化爲字符串

  • 字符串的自動轉換,主要發生在字符串的加法運算時
  • 當一個值是字符串,另外一個值是非字符串,相加,非字符串轉換成字符串
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]" ======> {} => toString => 返回類型字符串 '[object Object]'
'5' + [] // "5" =====================> [] => toString => 返回數組的字符串形式 '' => '5' + ''
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
複製代碼

自動轉化爲數值

  • 除了 + 有可能將運算子轉換成字符串,其餘運算符都會把運算子轉換成數值
  • 一元運算符也會把運算子轉成數值
'5' - '2' // 3
'5' * '2' // 10
true - 1  // 0
false - 1 // -1
'1' - 1   // 0
'5' * []    // 0 ----------------------- 5 * 0
false / '5' // 0 ----------------------- 0 / 5
'abc' - 1   // NaN --------------------- NaN - 1
null + 1 // 1 -------------------------- 0 + 1
undefined + 1 // NaN ------------------- NaN + 1



一元運算符也會把運算子轉成數值
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
複製代碼

運算符

加法運算符

  • 重載(overload): 加法運算符存在 相加 和 鏈接,運算子的不一樣,致使不一樣的語法行爲。
  • 除了加法運算符,其餘的運算符都不存在重載,將運算子都轉換成數值,再進行數學運算
  • 若是運算子是對象,必須先將對象轉成原始類型的值,而後再相加
1 + true // 2
1 + 'a' // "1a" ------------------- 數值和字符串新加,+存在重載,因此 1 被轉成字符串 '1'  =>  '1a'


(2) 重載致使運算結果的不一樣
'3' + 4 + 5 // "345"
3 + 4 + '5' // "75" ---------- 注意順序致使結果不同


(3) 運算子是對象
var obj = { p: 1 };
obj + 2 // "[object Object]2" 
------- valueOf => 對象自己{ p: 1 } => toString() => '[object Object]' + 2 => '[object Object]2'
------- 對象的valueOf返回對象自己
------- 注意:字符串和數值相加,因爲+存在重載, 此時 + 表示相連
------- 注意:toString()以後,+具備重載性,可能調用Number()也可能調用String()

複製代碼

null和undefined

  • null和undefined與自身嚴格相等
undefined === undefined // true
null === null // true


var v1; // undefined
var v2; // undefined
v1 === v2 // true

複製代碼

相等運算符 ==

  • 相等運算符,用來比較相同類型的數據時,與 嚴格相等運算符 等價
  • 相同類型的數據:== 和 === 等價
  • 不一樣類型的數據:== 會先進行類型轉化,再使用 === 比較
    • 原始類型的數據:轉成數值,再比較
    • 對象類型的數據:先將對象轉成原始類型的值,再比較
    • null和undefined:相互比較true,和任意其餘類型比較false
  • 缺點:存在隱式轉化,容易出錯
原始類型的值:先轉換成數值,再進行比較

1 == true // true
// 等同於 1 === Number(true)

'true' == true // false
// 都轉換成數值
// 等同於 Number('true') === Number(true)
// 等同於 NaN === 1

'1' == true  // true
// 等同於 Number('1') === Number(true)
// 等同於 1 === 1


false == 'false'    // false   // Number(false) == Number('false') => 0 === NaN => false
false == '0'        // true


----------------------------------------
對象類型的值: 先將對象轉成原始類型的值,再比較

[1] == 1 // true
// 等同於 Number([1]) == 1

[1] == '1' // true
// 等同於 Number([1]) == Number('1')

[1] == true // true
// 等同於 Number([1]) == Number(true)



----------------------------------------
null和undefined:相互比較true,和任意其餘類型比較false


false == null // false
false == undefined // false

0 == null // false
0 == undefined // false

undefined == null // true

false == undefined  // false 
--------------- undeined和null和任意其餘類型==比較,都返回false,相互==返回true
--------------- 原理:Number(false) == Number(undefined) => 0 === NaN => false
false == null       // false
null == undefined   // true
複製代碼

優先級

  • 最高優先級:屬性訪問擁有最高的優先級 . ()
  • 最低優先級:賦值運算符 = 擁有最低的優先級
  • 操做符中,一元運算符擁有最高優先級

結合性

  • 優先級相同時,如 乘和除,優先級相同時,考慮結合性
  • 結合性分類:左結合 和 右結合
  • 右結合:一元操做符,三元操做符,賦值操做符是右結合,其餘全部的操做符都是左集合
  • 左結合:其餘都是左結合

運算順序

  • 從左向右運算

isNaN 和 Number.isNaN

  • isNaN()先將參數轉換成number類型,再用isNaN判斷
  • Number.isNaN()先判斷參數是否是number類型,不是返回false,是再用isNaN就行判斷
var n = 1 / 'foo'
var a = 'str'

console.log(n) // 1/Number('foo') => 1/NaN => NaN
console.log(n == NaN) // NaN == NaN => false
console.log(NaN === NaN) // false
console.log(isNaN(n)) // true
console.log(isNaN(a)) // isNaN(Number('str')) => isNaN(NaN) => true
console.log(Number.isNaN(n)) // Number.isNaN(NaN) => true
console.log(Number.isNaN(a)) // Number.isNaN()先判斷參數是不是Number類型,false返回false, true再用isNaN判斷 => 直接false
複製代碼

案列1

[] == ![] 
// true

解析:
1. 優先級: ! > == 因此先算 ![] => false // 除了'',+-0,null,undefined,NaN是ture之外,其餘都是false
2. [] == false
3. == 相等運算符的運算子有對象時,先將[]轉換成原始類型的值,再比較
4. Number([]) == false => valueOf => [] => toString => '' => Number('') => 0 == false
5. 0 == false
6. 0 == Number(false) => 0 == 0 類型相同 == 等於 ===   => 0 === 0 => true
7. true
複製代碼

案列2

[] + []
// ''

解析:
1. + 的運算子是對象,先轉化成原始類型的值,而後再相加
2. [] => valueOf([]) => [] => toString([]) => ''
3. '' + ''
4. 字符串相加,+存在重載,這裏表示鏈接
5. ''
複製代碼
相關文章
相關標籤/搜索