一、比较运算符比较它的操作数并返回一个基于表达式是否为真的逻辑值。
1、操作数可以是数字,字符串,逻辑,对象值。
二、比较运算符
运算符 | 描述 | 返回true的示例 |
---|---|---|
等于 Equal(==) | 如果两边操作数相等时返回true | 3 == var1 ‘3’ == var1 |
不等于 Not equal(!==) | 如果两边操作数不相等时返回true | var1 != 4 var2 != ‘3’ |
全等 Strict equal(===) | 两边操作数相等且类型相同时返回true | 3 === var1 |
不全等 Strict not equal(!==) | 两边操作数不相等或类型不同时返回true | var1 !== ‘3’ |
大于 Greater than(>) | 左边的操作数大于右边的操作数返回true | var2 > var1 ‘12’ > 2 |
大于等于 Greater than or equal(>=) | 左边的操作数大于或等于右边的操作数返回true | var2 >= var1 |
小于 Less than(<) | 左边的操作数小于右边的操作数返回true | var1 < var2 ‘2’ < 12 |
小于等于 Less than or equal(<=) | 左边的操作数小于或等于右边的操作数返回true | var1 <= var2 var2 <=5 |
严格相等
一、普通的相等性检查==存在一个问题,它不能区分出0和false:
alert( 0 == false ); // true
也同样无法区分空字符串和false:
alert( '' == false ); // true
1、这是因为在比较不同类型的值时,处于相等判断符号==两侧的值会先被转化为数字。空字符串和false也是如此,转化后它们都为数字 0。
二、如果我们需要区分0和false,该怎么办?
1、严格相等运算符===在进行比较时不会做任何的类型转换。
(1)换句话说,如果a和b属于不同的数据类型,那么a === b不会做任何的类型转换而立刻返回false。
【示例1】
alert( 0 === false ); // false,因为被比较值的数据类型不同
Object.is() , a===b
一、有一个特殊的内建方法Object.is,它类似于===一样对值进行比较,但它对于两种边缘情况更可靠:
1、它适用于NaN:Object.is(NaN,NaN)=== true,这是件好事。
2、值0和-0是不同的:Object.is(0,-0)=== false,从技术上讲这是对的,因为在内部,数字的符号位可能会不同,即使其他所有位均为零。
二、在所有其他情况下,Object.is(a,b)与a === b相同。
三、这种比较方式经常被用在 JavaScript 规范中。当内部算法需要比较两个值是否完全相同时,它使用Object.is(内部称为SameValue)。
比较结果为 Boolean 类型
一、所有比较运算符均返回布尔值:
- true: 表示“yes(是)”,“correct(正确)”或“the truth(真)”。
- false: 表示“no(否)”,“wrong(错误)”或“not the truth(非真)”。
【示例1】
alert( 2 > 1 ); // true(正确)
alert( 2 == 1 ); // false(错误)
alert( 2 != 1 ); // true(正确)
二、和其他类型的值一样,比较的结果可以被赋值给任意变量:
let result = 5 > 4; // 把比较的结果赋值给 result
alert( result ); // true
各种数据类型之间的比较
比较规则
一、比较规则:当对不同类型的值进行比较时,JavaScript 会首先将其转化为数字(number)再判定大小。
| 【示例】```javascript alert( ‘2’ > 1 ); // true,字符串 ‘2’ 会被转化为数字 2 alert( ‘01’ == 1 ); // true,字符串 ‘01’ 会被转化为数字 1
|
| --- |
| 【示例】```html
console.log(({}==false)?true:false); // false
解析:{}==false,即({}).toString()=’[object Object]’, Number(‘[object Object]’)=NaN,最终比较的是NaN==0,即为false。②Boolean(false)为false。③false?true:false,结果为false | | —- |
二、对于布尔类型值,true会被转化为1、false转化为0。
【示例1】
alert( true == 1 ); // true
alert( false == 0 ); // true
三、有时候,以下两种情况会同时发生:
- 若直接比较两个值,其结果是相等的。
- 若把两个值转为布尔值,它们可能得出完全相反的结果,即一个是true,一个是false。
【示例1】
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(a == b); // true
1、对于 JavaScript 而言,这种现象其实挺正常的。因为 JavaScript 会把待比较的值转化为数字后再做比较(因此”0”变成了0)。若只是将一个变量转化为Boolean值,则会使用其他的类型转换规则。
字符串比较
一、在比较字符串的大小时,JavaScript 会使用“字典(dictionary)”或“词典(lexicographical)”顺序进行判定。
1、换言之,字符串是按字符(母)逐个进行比较的。
【示例1】
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
二、字符串的比较算法非常简单:字符串按字母顺序逐字比较
1、首先比较两个字符串的首位字符大小。
2、如果一方字符较大(或较小),则该字符串大于(或小于)另一个字符串。算法结束。
3、否则,如果两个字符串的首位字符相等,则继续取出两个字符串各自的后一位字符进行比较。
4、重复上述步骤进行比较,直到比较完成某字符串的所有字符为止。
5、如果两个字符串的字符同时用完,那么则判定它们相等,否则未结束(还有未比较的字符)的字符串更大。
三、非真正的字典顺序,而是 Unicode 编码顺序
1、在上面的算法中,比较大小的逻辑与字典或电话簿中的排序很像,但也不完全相同。
2、比如说,字符串比较对字母大小写是敏感的。大写的”A”并不等于小写的”a”。哪一个更大呢?实际上小写的”a”更大。这是因为在 JavaScript 使用的内部编码表中(Unicode),小写字母的字符索引值更大。
字符通过数字代码进行比较
一、一些奇怪的地方。
小写字母总是大于大写字母:
alert( 'a' > 'Z' ); // true
带变音符号的字母存在“乱序”的情况:
alert( 'Österreich' > 'Zealand' ); // true
(1)如果我们对这些国家名进行排序,可能会导致奇怪的结果。通常,人们会期望Zealand在名单中的Österreich之后出现。
二、为了明白发生了什么,我们回顾一下在 JavaScript 中字符串的内部表示。
1、所有的字符串都使用UTF-16编码。即:每个字符都有对应的数字代码。
三、有特殊的方法可以获取代码表示的字符,以及字符对应的代码。
1、str.codePointAt(pos):返回在pos位置的字符代码 : ```javascript // 不同的字母有不同的代码 alert( “z”.codePointAt(0) ); // 122 alert( “Z”.codePointAt(0) ); // 90
2、String.fromCodePoint(code):通过数字code创建字符
```javascript
alert( String.fromCodePoint(90) ); // Z
3、我们还可以用\u后跟十六进制代码,通过这些代码添加 unicode 字符:
// 在十六进制系统中 90 为 5a
alert( '\u005a' ); // Z
四、现在我们看一下代码为65..220的字符(拉丁字母和一些额外的字符),方法是创建一个字符串:
let str = '';
for (let i = 65; i <= 220; i++) {
str += String.fromCodePoint(i);
}
alert( str );
// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
// ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜ
1、先是大写字符,然后是一些特殊字符,然后是小写字符,而Ö几乎是最后输出。
2、现在很明显为什么a > Z。
3、字符通过数字代码进行比较。越大的代码意味着字符越大。a(97)的代码大于Z(90)的代码。
- 所有小写字母追随在大写字母之后,因为它们的代码更大。
一些像Ö的字母与主要字母表不同。这里,它的代码比任何从a到z的代码都要大。
正确的比较
一、执行字符串比较的“正确”算法比看起来更复杂,因为不同语言的字母都不相同。
二、因此浏览器需要知道要比较的语言。
三、幸运的是,所有现代浏览器(IE10- 需要额外的库Intl.JS) 都支持国际化标准ECMA-402。
1、它提供了一种特殊的方法来比较不同语言的字符串,遵循它们的规则。
2、调用str.localeCompare(str2)会根据语言规则返回一个整数,这个整数能表明str是否在str2前,后或者等于它:如果str小于str2则返回负数。
- 如果str大于str2则返回正数。
- 如果它们相等则返回0。
【示例1】
alert( 'Österreich'.localeCompare('Zealand') ); // -1
(1)这个方法实际上在文档中指定了两个额外的参数,这两个参数允许它指定语言(默认语言从环境中获取,字符顺序视语言不同而不同)并设置诸如区别大小之类的附加规则,或应该将”a”和”á”看作相等情况等。
null、undefined相关的比较
对 null 和 undefined 进行比较
一、当使用null或undefined与其他值进行比较时,其返回结果常常出乎你的意料。
二、规则
1、当使用严格相等===比较二者时
(1)它们不相等,因为它们属于不同的类型。
alert( null === undefined ); // false
2、当使用非严格相等==比较二者时
(1)JavaScript 存在一个特殊的规则,会判定它们相等。它们俩就像“一对恋人”,仅仅等于对方而不等于其他任何的值(只在非严格相等下成立)。
alert( null == undefined ); // true
3、当使用数学式或其他比较方法< > <= >=时:
(1)null/undefined会被转化为数字:null被转化为0,undefined被转化为NaN。
奇怪的结果:null vs 0
一、通过比较null和 0 可得:
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
1、在最后一行代码显示“null大于等于 0”的情况下,前两行代码中一定会有一个是正确的,然而事实表明它们的结果都是 false。
2、为什么会出现这种反常结果
(1)这是因为相等性检查==和普通比较符> < >= <=的代码逻辑是相互独立的。进行值的比较时,null会被转化为数字,因此它被转化为了0。这就是为什么(3)中null >= 0返回值是 true,(1)中null > 0返回值是 false。
(2)另一方面,undefined和null在相等性检查==中不会进行任何的类型转换,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。这就解释了为什么(2)中null == 0会返回 false。
| 【示例】下列语句运行后哪些打印的结果是false()
A. alert(2<1<3)
B. alert(3 == “3”)
C. alert(null == undefined)
D. alert(null == 0)
答案:D
解析:
A选项:2<1显示false, false在比较运算符中,先被转换为数字0再进行比较,也就是比较0<3,显示true
CD选项:
1. 相等性检查==和普通比较符> < >= <=的代码逻辑是相互独立的。
(1) 在进行值的比较值,null会被转化为数字再进行比较
(2) 在相等性检查==中,不能将null和undefined转换为其他任何值,除了它们之间互等外,不会等于任何其他的值。
|
| —- |
特立独行的 undefined
一、undefined不应该被与其他值进行比较:
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
1、返回值都是 false!
2、原因如下:
- (1)和(2)都返回false是因为undefined在比较中被转换为了NaN,而NaN是一个特殊的数值型值,它与任何值进行比较都会返回false。
(3)返回false是因为这是一个相等性检查,而undefined只与null相等,不会与其他值相等。
避免问题
一、避免潜在的问题:
除了严格相等===外,其他但凡是有undefined/null参与的比较,我们都需要格外小心。
除非你非常清楚自己在做什么,否则永远不要使用>= > < <=去比较一个可能为null/undefined的变量。对于取值可能是null/undefined的变量,请按需要分别检查它的取值情况。
数组比较
不要使用 == 比较数组
一、JavaScript 中的数组与其它一些编程语言的不同,不应该使用==运算符比较 JavaScript 中的数组。
因为该运算符不会对数组进行特殊处理,它会像处理任意对象那样处理数组。
二、规则:仅当两个对象引用的是同一个对象时,它们才相等==。
- 如果==左右两个参数之中有一个参数是对象,另一个参数是原始类型,那么该对象将会被转换为原始类型,转换规则如“数据类型的转换#对象与原始值之间的转换”https://www.yuque.com/tqpuuk/yrrefz/pcx42l#DGnVz。
- null和undefined相等==,且各自不等于任何其他的值。
数据比较
一、所以,如果我们使用==来比较数组,除非我们比较的是两个引用同一数组的变量,否则它们永远不相等。
【示例1】
alert( [] == [] ); // false
alert( [0] == [0] ); // false
1、从技术上讲,这些数组是不同的对象。所以它们不相等。==运算符不会进行逐项比较。
数组与原始类型的比较
一、与原始类型的比较也可能会产生看似很奇怪的结果:
alert( 0 == [] ); // true
alert('0' == [] ); // false
1、在这里的两个例子中,我们将原始类型和数组对象进行比较。因此,数组[]被转换为原始类型以进行比较,被转换成了一个空字符串’’。
2、然后,接下来的比较就是原始类型之间的比较,如类型转换一章所述:
// 在 [] 被转换为 '' 后
alert( 0 == '' ); // true,因为 '' 被转换成了数字 0
alert('0' == '' ); // false,没有进一步的类型转换,是不同的字符串