运算符是处理数据的基本方法,用来从现有的值得到新的值。JavaScript 提供了多种运算符,覆盖了所有主要的运算。
一.概述
- 比较运算符总览8个:
①>
:大于运算符;
②<
:小于运算符;
③<=
:小于或等于运算符;
④>=
:大于或等于运算符;
⑤==
:相等运算符;
⑥===
:严格相等运算符;
⑦!=
:不相等运算符;
⑧!==
:严格不相等运算符; - 比较运算符可以比较各种类型的值,不仅仅是数值
- 非相等性运算符有哪些?前4;相等性运算符有哪些?后4; 见上面总结
- 非相等性运算符的比较特点?
①分为2种:一种字符串比较,一种非字符串比较
②字符串比较,一个字符一个字符的码点进行比较
③非字符串比较中,原始类型转为数字比较,非原始类型(对象类型)调用valueOf()
,toString()
进行类型转换后比较
④具体见:非相等运算符 - 相等性运算符的比较特点?
①分为2种:一种严格相等符,一种非严格相等符
②严格相等符===
,!==
:判断类型是否一致,基础类型判断值,复合类型(对象,数组,函数)判断引用地址
③非严格相等符==
,!=
:相同类型判断方式与严格相等符相同;不同类型的原始值比较转为数值类型;对象与原始类型值比较尝试转换成原始类型
④具体见:相等运算符
二.非相等运算符
1.字符串之间比较
-
字符串按每个字符的字典顺序比较,引擎内部比较的是Unicode 码点
'cat' > 'dog' // false 'cat' > 'catalog' // false '大' > '小' // false
2.非字符串的比较
Ⅰ.原始类型
-
所有非数字原始类型都会转成数字然后比较;
-
若无法转换成数字,则会转换成NaN,任何数据和NaN(包括NaN本身)比较都会返回false;
//一 基础类型比较 5 > '4' // true // 等同于 5 > Number('4') // 即 5 > 4 true > false // true // 等同于 Number(true) > Number(false) // 即 1 > 0 2 > true // true // 等同于 2 > Number(true) // 即 2 > 1 2>'t'//false //'t'会转换为NaN比较会返回false //二 NaN比较 1 > NaN // false 1 <= NaN // false '1' > NaN // false '1' <= NaN // false NaN > NaN // false NaN <= NaN // false
Ⅱ.对象类型
-
对象转换为原始类型再比较,使用
valueOf
再调用返回数据的,toString
方法的值进行比较var x = [2]; x > '11' // true // 等同于 [2].valueOf().toString() > '11' // 即 '2' > '11' x.valueOf = function () { return '1' }; x > '11' // false // 等同于 [2].valueOf() > '11' // 即 '1' > '11' [2] > [1] // true // 等同于 [2].valueOf().toString() > [1].valueOf().toString() // 即 '2' > '1' [2] > [11] // true // 等同于 [2].valueOf().toString() > [11].valueOf().toString() // 即 '2' > '11' { x: 2 } >= { x: 1 } // true // 等同于 { x: 2 }.valueOf().toString() >= { x: 1 }.valueOf().toString() // 即 '[object Object]' >= '[object Object]'
三.相等性运算符
==
,!=
会进行类型转换,再在类型内比较;===
,!==
直接比较,如果类型不一致直接返回false;
1.严格相等运算符和严格不相等运算符
===
,!==
特性
(1).不同类型的值
-
不同类型的值,直接返回false
1 === "1" // false true === "true" // false
(2).同一类的原始类型值
-
数值、字符串、布尔值的值相同返回true,如下值比较特殊
//10进制1与16进制1相同 1 === 0x1 // true NaN === NaN // false +0 === -0 // true
(3).复合类型的值
-
两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个地址;
-
对于复合函数来说,
===
,!==
比较的是地址引用;而>
,>=
,<
,<=
比较的是值//比较地址 {} === {} // false [] === [] // false (function () {} === function () {}) // false var v1 = {}; var v2 = v1; v1 === v2 // true var obj1 = {}; var obj2 = {}; obj1 >= obj2 // true [object Object] >= [object Object] obj1 <= obj2 // true obj1 === obj2 // false
(4).undefined 和 null
-
undefined和null与自身严格相等
-
由于变量声明后默认值是undefined,因此两个只声明未赋值的变量是相等的
undefined === undefined // true null === null // true var v1; var v2; v1 === v2 // true
(5).严格不相等运算符
- 严格相等运算符有一个对应的“严格不相等运算符”(!==),它的算法就是先求严格相等运算符的结果,然后返回相反值
2.相等运算符和不相等运算符
==
,!=
特性
(1).相同类型
- 在比较相同类型的数据时,与严格相等运算符完全一样
(2).不同类型:原始类型值(Number,Boolean,String)
-
原始类型值会转换为数值比较
1 == true // true // 等同于 1 === Number(true) 0 == false // true // 等同于 0 === Number(false) 2 == true // false // 等同于 2 === Number(true) 2 == false // false // 等同于 2 === Number(false) 'true' == true // false // 等同于 Number('true') === Number(true) // 等同于 NaN === 1 '' == 0 // true // 等同于 Number('') === 0 // 等同于 0 === 0 '' == false // true // 等同于 Number('') === Number(false) // 等同于 0 === 0 '1' == true // true // 等同于 Number('1') === Number(true) // 等同于 1 === 1 '\n 123 \t' == 123 // true // 因为字符串转为数字时,省略前置和后置的空格
(3).对象与原始类型值比较
-
对象(这里指广义的对象,包括数组和函数)与原始类型的值比较时,对象转换成原始类型的值,再进行比较
// 对象与数值比较时,对象转为数值 [1] == 1 // true // 等同于 Number([1]) == 1 // 对象与字符串比较时,对象转为字符串 [1] == '1' // true // 等同于 String([1]) == '1' [1, 2] == '1,2' // true // 等同于 String([1, 2]) == '1,2' // 对象与布尔值比较时,两边都转为数值 [1] == true // true // 等同于 Number([1]) == Number(true) [2] == true // false // 等同于 Number([2]) == Number(true)
(4).undefined 和 null
-
undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true
false == null // false false == undefined // false 0 == null // false 0 == undefined // false undefined == null // true
(5).相等运算符的缺点
-
相等运算符隐藏的类型转换,会带来一些违反直觉的结果
0 == '' // true 0 == '0' // true 2 == true // false 2 == false // false false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' \t\r\n ' == 0 // true