JavaScript 操作符总结

本文详细讲解了JavaScript中判等操作符(==,===)的区别,比较操作符(>,<,==,<=,>=)的规则,以及运算符(+,-,*,/)的行为。强调了理解运算符的工作流程和避免凭直觉编程的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇主要说三类操作符的使用,分别是 判等操作符 比较操作符 运算符,建议先看一下我的上一篇《JavaScript 类型转换全面总结》保证你对js中类型的转换有充分的了解。

开篇先说一下在学习操作符和类型转换中get到的一些体会 "请不要 相信直觉!" 了解清楚每个操作符的运算比较流程,而不要凭借"语感"来作出判断!

判等 == & ===

首先我们来说一下判等运算符的使用,我们知道js中判断相等可以使用 == 和 === ,他们的区别是

  •  == 允许在比较的同时进行类型转换,如果比较双方类型不同,会先尝试转成相同的类型,再进行判断
  • === 不允许比较的双方在比较时类型转换,类型不同会直接判定为不同

== 的判定会相对宽松一些,其判定的规则可以主要归纳为:

1. 如果双方都是复杂类型,则判断双方的地址是否一致 如 {} != {} 因为两个{}是两个不同的地址

2. 如果双方都是简单类型,并且类型相同,则可以直接判断其是否相等

3.如果双方都是简单类型,并且类型不相同,则都转换为数字类型进行比较 如 '1' == true 为true 即: ‘1’ -> 1 true-> 1

4. 如果有一方是复杂类型,则先求复杂类型的原始值[[Primitive]] 在得到原始值之后再按照简单类型比较 

5. NaN和任何值都不等,即使两个NaN也不相等,任何两个Symbol也都不相等,也不等于任何值

6. null == undefined 但是不等于这俩以外的任何值

对于 === 则简单得多

1. 对于类型不同的,直接不等

2. 对于两个复杂类型,则判断其地址是否相等

3. NaN 不全等于任何值,Symbol也不全等于任何值

4. undefined和null算是两个不同的类型,互相不相等

我们可以利用这个特性 如

if( a == null ) 或者 if( a == undefined )

这样 a为null或者undefined的时候,都可以被检测到!

下面我们看一些例子运用上面的规则:

null == undefined // true null和undefined默认相等
'NaN' == NaN //false NaN和任何值都不相等
5 == NaN // false NaN和任何值都不相等
NaN == NaN //false NaN和任何值都不相等
NaN != NaN // true
false == 0 // true 同为简单类型,且类型不同,都转换为数字类型比较 false->0 为true
true == 1 // true 原理同上
true == 2 // false 因为true转成数字为1 

这里需要注意,我们在代码中判断一个值是不是为真时,不要用以下的方式

if( a == true ) { ... }

因为如果a是1以外的数字,这个判断都是为false的,而我们需要的是,0判断为false,其他值都为true。

我们可以使用 if(!!a) 或者 if(a) if(Boolean(a))等方式!

undefined == 0 // false undefined 不等于null以外的任何值
null == 0 // false null不等于undefined以外的任何值
'5' == 5 // true 不同类型的简单类型比较,都转换为数字 5 ==5 为真

var a = 42
var b = [42]
a == b // true
当比较双方有一方是复杂类型时,会先调用其[[Primitive]]求原始值,[42]的toString方法返回"42" 其原始值为"42" 就转变成了 42 == "42" 都转换成数字比较 为true

var a = "abc"
var b = new String(a)
a == b //true
a === b // false 
a为简单类型 b为a的包装对象,为复杂类型,所以a === b自然为false
b为复杂类型,a==b比较时,先调[[Primitive]] 求b的原始值 包装对象的valueOf值为"abc" 所以a==b

我们称包装对象的.valueOf() 为"拆封"

var a = null
var b = new Object()
a == b //false
b为复杂类型,求原始值为"[object Object]" 不是null或者undefined 所以为false

var c = undefined
var d = new Object()
c == d //false 和上面同理

var e = NaN
var f = new Number(e)
e == f //false
f为包装对象,其开封后值为NaN 但是NaN和任何值都不等 另外一个NaN也不行,所以为false
[] == ![] // true
首先 ![] 转成false []==false , []是复杂类型,其原始值为"" 转变成 "" == false 类型不同都转成数字 即 0 == 0 true

2 == [2] //true [2]原始值为 "2" 2=="2" true

"" == [null] //true [null]的原始值是 "" 不是 "null" 这里不明白的可以看我上一篇文章,简单来说就是null是数组中的占位符,toString函数会跳过null,同样被跳过的还有undefiend

"true" == true //false 这个就是凭借直觉很容易错的,由于两个比较的值都是简单类型,则转换成数字类型 "true"->NaN NaN和任意值不等 为false

"foo" == ["foo"] 这个不用多说了 true

 是不是晕了?? 如果晕了 请多看几遍,对照着最上面 == 和 === 比较的规则,忘掉脑中的直觉。多试几次!

比较 > < >= <= 

下面看和比较有关的操作符,即 >, <, >=, <=

比较的规则比较简单 

1. 如果比较的双方都是字符串,则按照ASCII的顺序逐个字符比较大小

2. 如果比较的双方都是简单类型,则转换成数字比较

3. 如果比较多双方存在复杂类型,则先转换成原始值,在根据简单类型的规则进行比较!

4. NaN 不能和任何值比大小

5. null和undefined可以转换成数字比较大小

看一些例子:

console.log(null>-1);//true null-> 0
console.log(null>=-1);//true null->0
console.log(null<1);//true null->0
console.log(null<=1);//true null->0

console.log(null==0);//false. null和undefined无法类型转换 
console.log(null===0);//false 类型不同 不等
console.log(null!=0);//true null和undefined无法类型转换
console.log(null!==0);//true 类型不同 不等
注意! 等号 == / === 需要按照相等操作的规则判断

这里注意一个很容易错的点:

undefined  -> NaN null ->0 之后比较只存在于 比较符 即可 > < >= <= 中,可以这么转换,但是在 == 或 === 中 这俩值不等于他们以外的任何值,需要按照判等的规则看!

console.log('2' > 10);//false
都转成数字类型比较 2<10
 
console.log('2' > '10');//true
都是字符串,按照每位的ASCII比较,其中'2'的ASCII>'1'的ASCII
console.log('10'.charCodeAt());//49
 
console.log('a' > 'b');//false
a的ascii小于b的ascii
 
console.log(‘a’>’A’)//true 
小写字母的ascii大于大写字母
 
console.log('abc' > 'b');//false
a的ascii<b的ascii

console.log('abc' > 'aad');//true
第一位都是a ascii相同 第二位 b > a
var a = { b: 42 }
var b = { b: 43 }

a<b // false a b都是复杂类型,转换成原始值都是 "[object Object]" 所以为false
a==b // false 这里很容易混淆,注意a b都是复杂类型,需要比较地址 明显不同
a>b //false 和 a<b同理

a<=b // true <= 属于比较运算,不是判等运算,则不需要判断地址,a b 都是"[object Object]" 满足
a>=b // true 同上

注! javaScipt中的 > < >= <= 和数学中的不太一样,需要区分! 

运算符 + - * / 

+ - * / 最好理解,只需要记 + 有特殊

1. + 运算符,如果两边都是有字符串,就是字符串拼接,如果没有字符串,就都转成数字运算

2. - * / 都转换成数字运算

3. 复杂类型需先转换成简单类型!

看一些例子! 

console.log('' + 1)//'1' -> "" + "1" -> "1"
console.log('a' + 1);//'a1' -> "a"+"1" -> "a1"
console.log('1' + 1);//'11' -> "1"+"1" => "11"
console.log(NaN + 1);//NaN  运算符两边都不是字符串,转成数字为NaN
console.log(true + 1);//2 -> 1+1 = 2
console.log(false + 1);//1 -> 0+1 = a
console.log(null + 1);//1 -> 0 + 1 = 1
console.log(undefined + 1);//NaN 注意 undefined转成数字为NaN null转成数字才是0 

console.log([] + 1)//"1"  []的原始值为"" ""+1 -> ""+"1" = "1"
console.log([1, 2, 3] + 1);//'1,2,31' [1,2,3]的原始值为"1,2,3" 相加为"1,2,31"

console.log({} + 1);
// -> "[object Object]"+1 -> "[object Object]"+"1" -> '[object Object]1'

console.log({ a: 1 } + 1);//'[object Object]1' 同理
注意 - * / 一律转换为数字运算
console.log('' - 1)//-1 -> 0-1 = -1
console.log('a' - 1);//NaN NaN和任意运算都是NaN
console.log('1' - 1);//0 -> 1-1=0
console.log(NaN - 1);//NaN NaN和任意运算都是NaN
console.log(true - 1);//0 -> 1-1 = 0
console.log(false - 1);//-1 -> 0-1 = -1
console.log(null - 1);//-1 -> 0-1=-1
console.log(undefined - 1);//NaN -> NaN - 1 ->  NaN和任意运算都是NaN

console.log([] - 1)//-1 -> ""-1 -> 0-1 = -1
console.log([1, 2, 3] - 1);//NaN -> "1,2,3"-1 = NaN
console.log({} - 1);//NaN "[object Object]"-1 = NaN
console.log({ a: 1 } - 1);//NaN "[object Object]"-1 = NaN

最后,附上一张图吧! 看完了上面的内容,你能否看懂下面的图呢? 

务必,不要相信直觉!!! 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值