日常咱們都是不建議在代碼上編寫一些比較難理解的代碼,例如 x == y
和 'A' > 'B'
。這篇文章或許不能給你帶來什麼大的幫助,可是卻可讓你瞭解一些你可能沒接觸到的知識點。html
因爲有些參考資料來源於 ECMA 規範,因此感興趣的可能須要先看《讀懂 ECMAScript 規格》這篇文章,固然也能夠忽略。es6
首先咱們須要先了解基本的類型轉換規則。ui
粗體須要特別留意的,可能跟你想象中的不同。spa
原始值 | 轉換爲數字 | 轉換爲字符串 | 轉換爲布爾值 |
---|---|---|---|
false | 0 | "false" | false |
true | 1 | "true" | true |
0 | 0 | "0" | false |
1 | 1 | "1" | true |
"0" | 0 | "0" | true |
"000" | 0 | "000" | true |
"1" | 1 | "1" | true |
NaN | NaN | "NaN" | false |
Infinity | Infinity | "Infinity" | true |
-Infinity | -Infinity | "-Infinity" | true |
"" | 0 | "" | false |
"20" | 20 | "20" | true |
"Runoob" | NaN | "Runoob" | true |
[ ] | 0 | "" | true |
[20] | 20 | "20" | true |
[10,20] | NaN | "10,20" | true |
["Runoob"] | NaN | "Runoob" | true |
["Runoob","Google"] | NaN | "Runoob,Google" | true |
function(){} | NaN | "function(){}" | true |
{ } | NaN | "[object Object]" | true |
null | 0 | "null" | false |
undefined | NaN | "undefined" | false |
這裏根據上面的表格列舉些例子:.net
數字轉字符串code
這個最經常使用了,這個也很好理解。htm
String(123)
複製代碼
或者對象
const a = 123;
a.toString();
複製代碼
將字符串轉換爲數字blog
Number("3.14") // 返回 3.14
Number(" ") // 返回 0
Number("") // 返回 0
Number("99 88") // 返回 NaN
複製代碼
字符串轉布爾值索引
Boolean('test') // 返回 true
Boolean('0') // 返回 false
Boolean('000') // 返回 true
複製代碼
規則來源於 ECMA 相關規範 Abstract Equality Comparison。
==
等同運算符的兩邊的類型不同的時候,會有類型自動轉換規則。
相同的類型能夠直接比較(至關於 ===
比較),無需自動轉換,不一樣類型有下面幾種自動轉換規則(x == y
),規則優先級自上而下:
若是 x 是 null,y 是 undefined,返回 true
null == undefined
複製代碼
若是 x 是 undefined,y 是 null,返回 true
undefined == null
複製代碼
若是 x 是 Number,y 是 String,將 y 轉化成 Number,而後再比較
0 == '0' // true
0 == '1' // false
複製代碼
若是 x 是 String,y 是 Number,將 x 轉化成 Number,而後再比較
'0' == 0 // true
'1' == 0 // false
複製代碼
若是 x 是 Boolean,那麼將 x 轉化成 Number,而後再比較
true == 0 // false
true == 1 // true
true == 2 // false
true == 'test' // false
false == 0 // true
false == 1 // false
false == 2 // false
false == 'test' // false
複製代碼
若是 y 是 Boolean,那麼將 y 轉化成 Number,而後再比較
0 == true // false
1 == true // true
2 == true // false
'test' == true // false
0 == false // true
1 == false // false
2 == false // false
'test' == false // false
複製代碼
若是 x 是 String 或者 Number,y 是 Object,那麼將 y 轉化成基本類型,再進行比較
const a = {}
1 == a // false
'1' == a // false
複製代碼
若是 x 是 Object,y 是 String 或者 Number,將 x 轉化成基本類型,再進行比較
const a = {}
a == 1 // false
a == '1' // false
複製代碼
其餘狀況均返回 false
const a = {}
a == null
a == undefined
0 == null
'2' == null
false === null
複製代碼
即便咱們搞懂了 ==
的規則,仍是建議使用 ===
這種嚴格的運算符來替代 ==
。
規則來源於 ECMA 相關規範 Abstract Relational Comparison。
x < y
的規則步驟以下(規則優先級自上而下):
x 和 y 須要轉換爲原始數據類型(ToPrimitive)
var px = ToPrimitive(x)
var py = ToPrimitive(y)
// 下面會沿用這兩個變量的
複製代碼
除開原始的數據類型 undefined、null、boolean、number、string、 symbol,其餘的都屬於對象,因此能夠理解爲這個 ToPrimitive 只對對象有做用。(還有個特殊的 NaN,不須要轉換,NaN 能夠理解爲一種特殊的 number,typeof NaN === 'number')。
若是 x 或者 y 是對象,須要作轉換處理,因爲這裏涉及的比較深,這裏仍是簡單的說一下,知道有這回事就好。
var a = {}
a < 'f' // true
a < 'F' // false
// a 會轉變爲 [object Object]
// 至關於運行了 a.valueOf().toString()
複製代碼
爲何不直接 a.toString() 呢,看下下面的例子你就懂了(會首先運行 valueOf,若是返回的是對象則再運行 toString,不然直接返回 valueOf 的返回值)
var d = new Date(1572594637602)
d < 1572594637603 // true
d < 1572594637601 // false
// d 會轉變爲 1572594637602 (當前時間轉變的成的毫秒時間戳)
// 至關於運行了 a.valueOf()
複製代碼
若是重寫了 valueOf 方法,那麼預期結果就不同了
var d = {}
// 這裏重寫定義了valueOf
d.valueOf = () => 1
d < 2 // true
d < 0 // false
// d 會轉變爲 1
// 至關於運行了 a.valueOf()
複製代碼
更多的例子
var a = {}
a < 1 // false,至關於,Number('[object Object]') < 1
a < 'a' // true,至關於 '[object Object]' < 'a'
a < '[' // false,至關於 '[object Object]' < '['
var b = function(){}
b < 'g' // true,至關於 'function(){}' < 'g'
b < 'e' // false,至關於 'function(){}' < 'e'
複製代碼
若是 px 和 py 都是字符串
若是 py 是 px 的前綴,返回 false
'test' < 'te'
複製代碼
若是 px 是 py 的前綴,返回 true
'test' < 'test1'
複製代碼
若是 px 不是 py 的前綴,並且 py 也不是 px 的前綴
那麼須要從 px 和 py 的最小索引(假設是 k)對應的**字符的 UTF-16 代碼單元值 **進行對比。
假設 m = px.charCodeAt(k),n = py.charCodeAt(k),那麼若是 m < n,返回 true,不然返回 false。
'A' < 'B' // true
// 至關於 'A'.charCodeAt(0) < 'B'.charCodeAt(0)
複製代碼
更加複雜點的例子
'ABC' < 'ABD' // true
// 至關於
// var a = 'ABC'.charCodeAt(0) < 'ABD'.charCodeAt(0) // false
// var b = 'ABC'.charCodeAt(1) < 'ABD'.charCodeAt(1) // false
// var c = 'ABC'.charCodeAt(2) < 'ABD'.charCodeAt(2) // true
// a || b || c
複製代碼
其餘狀況 px 和 py 一概轉爲數字類型進行比較
var nx = Number(px)
var ny = Number(py)
複製代碼
例子
'2' < 3 // true
'2' < 1 // false
複製代碼
x > y
的道理同樣,這裏就很少說了。