你真的理解了比较运算符吗?

更新日期: 2019-11-01阅读: 1.5k标签: 运算

平常我们都是不建议在代码上编写一些比较难理解的代码,例如 x == y 和 'A' > 'B' 。这篇文章或许不能给你带来什么大的帮助,但是却可以让你了解一些你可能没接触到的知识点。

由于有些参考资料来源于 ECMA 规范,所以感兴趣的可能需要先看《读懂 ECMAScript 规格》这篇文章,当然也可以忽略。


类型之间的转换表

首先我们需要先了解基本的类型转换规则。

粗体需要特别留意的,可能跟你想象中的不一样。

原始值转换为数字转换为字符串转换为布尔值
false0"false"false
true1"true"true
00"0"false
11"1"true
"0"0"0"true
"000"0"000"true
"1"1"1"true
NaNNaN"NaN"false
InfinityInfinity"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
null0"null"false
undefinedNaN"undefined"false

这里根据上面的表格列举些例子:

数字转字符串

这个最常用了,这个也很好理解。

String(123)

或者

const a = 123;
a.toString();

将字符串转换为数字

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(a) < 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 的道理一样,这里就不多说了。


链接: https://www.fly63.com/article/detial/6233

js除了Math.floor方法,还可以通过位运算|,>>实现向下取整

我们都知道通过Math.floor()方法可实现数值的向下取整,得到小于或等于该数字的最大整数。除了Math.floor方法,还可以使用位运算|,>>来实现向下取整哦

es6 扩展运算符 三个点(...)

扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

巧用JS位运算

位运算的方法在其它语言也是一样的,不局限于JS,所以本文提到的位运算也适用于其它语言。位运算是低级的运算操作,所以速度往往也是最快的

js中使用位运算,让执行效率更高

平常的数值运算,其本质都是先转换成二进制再进行运算的,而位运算是直接进行二进制运算,所以原则上位运算的执行效率是比较高的,由于位运算的博大精深,下面通过一些在js中使用位运算的实例

js各种取整方式及方法_四舍五入、向上取整、向下取整

js实现:四舍五入、向上取整、向下取整等方法。parseInt、Math.ceil、Math.round、Math.floor、toFixed等的使用

JavaScript循环计数器

JS经常会遇到延迟执行的动作,并且失败后自动尝试,尝试N次之后就不再尝试的需求,今天刚好又遇到,于是写个闭包,以后不断完善继续复用。检查并计数第一个参数用来标记是尝试哪个动作的,第二个参数是最大尝试次数

js 位运算符_js按位运算符及其妙用

大多数语言都提供了按位运算符,恰当的使用按位运算符有时候会取得的很好的效果。在我看来按位运算符应该有7个:& 按位与、| 按位或、^ 按位异或、~ 按位非

PHP取整、四舍五入取整、向上取整、向下取整、小数截取

PHP取整数函数常用的四种方法:1.直接取整,舍弃小数,保留整数:intval(); 2.四舍五入取整:round(); 3.向上取整,有小数就加1:ceil(); 4.向下取整:floor()。

JavaScript 中的相等操作符 ( 详解 [] == []、[] == ![]、{} == !{} )

ECMAScript 中的相等操作符由两个等于号 ( == ) 表示,如果两个操作数相等,则返回 true。相等操作符会先转换操作数(通常称为强制转型),然后比较它们的相等性。

关于js开发中保留小数位计算函数(以向上取整或向下取整的方式保留小数)

前端工作中经常遇到数字计算保留小数问题,由于不是四舍五入的方式不能使用toFixed函数,本文采用正则表达式匹配字符串的方式,解决对数字的向上或向下保留小数问题:

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!