前面的話
關系運算符用于測試兩個值之間的關系,根據關系是否存在而返回true或false,關系表達式總是返回一個布爾值,通常在if、while或for語句中使用關系表達式,用以控制程序的執行流程
javascript提供了===、!==、==、!=、<、<=、>、>=8個關系運算符,本文將分為4類介紹關系運算符
恒等運算符
恒等運算符'===',也叫嚴格相等運算符,首先計算其操作數的值,然后比較這兩個值,比較過程沒有任何類型轉換,比較過程如下:
【1】如果兩個值的類型不相同,則返回false
console.log(1 === '1');//false console.log(1 === [1]);//false
【2】如果兩個值都是Undefined、Null、Boolean、Number、String相同原始類型的值,值相同,就返回true,否則,返回false
console.log(undefined === undefined);//true console.log(null === null);//true
console.log(true === true);//true console.log(false === false);//true
console.log(1 === 1);//true console.log(2.5 === 2.5);//true
[注意]不論什么進制的數字,在進行關系比較時,最終都轉換為十進制進行運算
console.log(10 === 0xa);//true
在數字Number類型中,有一個值比較特殊,是NaN(not a number),它與任何值都不相等;此外,數字Number類型中存在著+0和-0,雖然其符號不同,但值相等
console.log(NaN === NaN);//false console.log(+0 === -0);//true
兩個相同字符串值表現為:相同的長度和相同的字符對應相同的位置
console.log('abc' === 'abc');//true console.log('abc' === 'acb');//false
【3】如果兩個值引用同一個對象,則返回true,否則,返回false
[注意]更詳細的解釋是,javascript對象的比較是引用的比較,而不是值的比較。對象和其本身是相等的,但和其他任何對象都不相等。如果兩個不同的對象具有相同數量的屬性,相同的屬性名和值,它們依然是不相等的
console.log([] === []);//false console.log({} === {});//false console.log(function(){} === function(){});//false
var a = {}; b = a; console.log(a === b);//true
【恒不等運算符】
恒不等運算符(!==)又叫嚴格不等于運算符,操作數的比較過程與恒等運算符相同,結果取反。如果'==='的比較結果是true,則'!=='的比較結果是false;如果'==='的比較結果是false,則'!=='的比較結果是true
console.log(1 !== '1');//true console.log(1 !== 1);//false console.log(true !== false);//true console.log({} !== {});//true
相等運算符
相等運算符'=='和恒等運算符相似,但相等運算符的比較并不嚴格,如果兩個操作數不是同一類型,相等運算符會嘗試進行一些類型轉換,然后再進行比較
當兩個操作數類型相同時,比較規則和恒等運算符規則相同
console.log(undefined == undefined);//true console.log(10 == 0xa);//true console.log(NaN == NaN);//false console.log([] == []);//false
當兩個操作數類型不同時,相等運算符'=='會遵守如下規則:
【1】如果一個值是對象類型,另一值是原始類型,則對象類型會先使用valueOf()轉換成原始值,如果結果還不是原始值,則再使用toString()方法轉換,再進行比較
[注意]日期類只允許使用toString()方法轉換為字符串。類似地,時間Date對象進行加法運算時使用toString()轉換為字符串,而在其他數學運算,包括減法、乘法、除法、求余等運算中,都是使用Number()轉換函數將時間Date對象使用valueOf()轉換為數字
【2】在對象轉換為原始值之后,如果兩個操作數都是字符串,則進行字符串的比較
console.log(new Date() == 'Sat Jun 25 2016 11:07:20 GMT+0800 (中國標準時間)');//true
【3】在對象轉換為原始值之后,如果至少有一個操作數不是字符串,則兩個操作數都將通過Number()轉型函數轉換成數字進行數值比較
console.log(true == 1);//true console.log(true == 0);//false console.log(false == '1');//false console.log(false == '0');//true console.log(true == 'true');//false,相當于1 == NaN console.log([1] == 1);//true,相當于1 == 1 console.log([1] == '1');//true,相當于'1' == '1' console.log([] == 0);//true,相當于0 == 0 console.log([] == '0');//false,相當于'' == '0' console.log([] == true);//false,相當于0 == 1 console.log([1] == true);//true,相當于1 == 1
var a = { valueOf:function(){ return 1; }, toString:function(){ return '2'; } } console.log( a == '1');//true,相當于1 == 1 var a = { valueOf:function(){ return {}; }, toString:function(){ return '1'; } } console.log( a == 1);//true,相當于1 == 1
[注意]如果一個值是null,另一個值是undefined,則返回true。雖然Number(null)是0,但null和0并不相等
console.log(null == undefined);//true console.log(null == 0);//false
[注意]空字符串或空格字符串會轉成0
console.log(null == []);//false console.log(null == '');//false console.log([] == ' ');//false,相當于'' == ' ' console.log([] == '');//true,相當于'' == '' console.log(0 == '');//true
【不相等運算符】
不相等運算符(!=)的操作數比較過程與相等運算符相同,結果取反。如果'=='的比較結果是true,則'!='的比較結果是false;如果'=='的比較結果是false,則'!='的比較結果是true
console.log(1 != '1');//false,相當于1 != 1 console.log(true != '1');//false,相當于1 != 1 console.log('true' != 1);//true,相當于NaN != 1 console.log([1] != '1');//false,相當于'1' != '1' console.log([1] != true);//false,相當于1 != 1
大于運算符
大于運算符(>)用于比較兩個操作數,如果第一個操作數大于第二個操作數,則大于運算符的計算結果為true,否則為false
大于運算符的操作數可能是任意類型,然而,只有數字和字符串才能真正執行比較操作,因此那些不是數字和字符串的操作數都將進行類型轉換,類型轉換規則如下:
【1】如果操作數是對象,則這個對象將先使用valueOf()轉換成原始值,如果結果還不是原始值,則再使用toString()方法轉換
[注意]實際上,在原生對象中,使用valueOf()方法轉換為原始值的,只有轉換為數字Number類型的時間Date對象,其他對象都通過toString()方法轉換為字符串
【2】在對象轉換為原始值之后,如果兩個操作數都是字符串,則按照字母表的順序對兩個字符串進行比較,這里提到的字母表順序是指組成這個字符串的16位unicode字符的索引順序
console.log('b' > 'a');//true console.log('B' > 'a');//false console.log({} > '[a]');//true,相當于'[object Object]' > '[a]' console.log({} > '[p]');//false,相當于'[object Object]' > '[p]' console.log(['a'] > ['b']);//false,相當于'a' > 'b' console.log([2] > [11]);//true,相當于'2' > '11'
[注意]在字母表中大寫字母在小寫字母的前面,所以大寫字母 < 小寫字母;但字符串String對象有一個字符串比較的方法localeCompare()方法會考慮自然語言的排序情況,把'B'排在'a'的后面,如果字符串在字母表中排在其參數之前時,則該方法返回一個負數;字符串在字母表中排在其參數之后時,返回一個正數
console.log('B'.localeCompare('a'));//1 console.log('B' > 'a');//false console.log('b'.localeCompare('a'));//1 console.log('b' > 'a');//true
【3】在對象轉換為原始值之后,如果至少有一個操作數不是字符串,則兩個操作數都轉換成數字進行比較
[注意]在等于操作符中,時間Date()對象只允許通過toString()方法轉換為字符串,而不允許通過valueOf()方法轉換為數字;而在大于操作符中,時間Date()對象允許優先使用valueOf()方法轉換為數字
console.log(new Date() > 100);//true,相當于1466826928667 > 100 console.log(true > [0]);//true,相當于 1 > 0 console.log(2 > 1);//true console.log(11 > '2');//true,相當于11 > 2 console.log(NaN > 1);//false console.log(1 > NaN);//false console.log({} > true);//false,相當于 NaN > 1
[注意]null == 0的結果為false,這是因為javascript將null == undefined的結果設為true。在大于運算中,null和undefined進行Number()轉型函數轉換分別轉換為0和NaN
console.log(undefined > -1);//false,相當于NaN > -1 console.log(null > -1);//true,相當于0 > -1 console.log(undefined > 0);//false,相當于NaN > 0 console.log(null > 0);//false,相當于0 > 0
對于數字和字符串來說,加號運算符和比較運算符的行為有所不同,加號運算符更偏愛字符串,如果它的一個操作數是字符串,就進行字符串連接。而比較運算符則更偏愛數字,只有在兩個操作數都是字符串時,才進行字符串的比較
console.log(1 + 2);//3 console.log('1' + '2');//'12' console.log('1' + 2);//'12',相當于 '1' + '2' console.log(2 > 1);//true console.log('2' > '1');//true console.log('2' > 1);//true,相當于 2 > 1
【小于等于運算符】
小于等于運算符(<=)并不依賴于小于或等于運算符的比較規則,而是遵循大于運算符的比較規則,結果取反。如果'>'的比較結果是true,則'<='的比較結果是false;如果'>'的比較結果是false,則'<='的比較結果是true
console.log(1 <= '0');//false,相當于1 <= 0 console.log(true <= '0');//false,相當于1 <= 0 console.log('true' <= 0);//false,相當于NaN <= 0 console.log([1] <= '0');//false,相當于'1' <= '0' console.log([0] <= true);//true,相當于0 <= 1 console.log(1 <= 1);//true
小于運算符
小于運算符(<)用于比較兩個操作數,如果第一個操作數小于第二個操作數,則小于運算符的計算結果為true,否則為false
小于運算符與大于運算符的類型轉換規則類似,就不再贅述
【大于等于運算符】
同樣地,大于等于運算符(>=)并不依賴于大于或等于運算符的比較規則,而是遵循小于運算符的比較規則,結果取反。如果'<'的比較結果是true,則'>='的結果是false;如果'<'的比較結果是false,則'>='的結果是true
參考資料
【1】 ES5/關系運算符 https://www.w3.org/html/ig/zh/wiki/ES5/expressions
【2】 阮一峰Javascript標準參考教程——語法——比較運算符 http://javascript.ruanyifeng.com
【3】 W3School-Javascript高級教程——ECMAScript關系運算符 http://www.w3school.com.cn
【4】《javascript權威指南(第6版)》第4章 表達式和運算符
【5】《javascript高級程序設計(第3版)》第3章 基本概念
【6】《javascript DOM編程藝術(第2版)》第2章 Javascript語法
文章列表