You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
比较 x < y(其中 x 和 y 是值)会产生 true,false 或 undefined(这表明至少一个操作数是 NaN)。除x和y外,该算法还使用名为 LeftFirst 的布尔标志作为参数。该标志用于控制对 x 和 y 执行具有潜在可见副作用的操作的顺序。LeftFirst 默认为 true。
比较
先看代码:
上面的代码,我能说出所有的正确打印结果吗?如果能的话,我能说出所有的比较原理吗?
对不起,我都做不到。比如对象之间比较以及
Symbol
与Number
的比较,我不敢说出结果,因为我没手动测试过,更对其原理一无所知,所以我遇到这些完全没底气!其他的方法可以不看,主要是以下的与比较有直接关联的方法:
IsStringPrefix ( p, q )
判断字符串
p
是不是字符串q
的前缀。p
和q
都必须是字符串q
可以是p
和其他字符串r
的串联,返回true
,否则返回false
r
可能是空字符串SameValue ( x, y )
fasle
x
是不是Number
或BigInt
,然后对x
和y
执行sameValue
(BigInt::sameValue ( x, y ),Number::sameValue ( x, y ))操作比较SameValueNonNumeric(x, y)
后的值SameValueZero ( x, y )
其实本质和
SameValue
区别不大,只是它只比较 +0 和 -0。SameValueNonNumeric ( x, y )
最终会返回
true
或false
。x
和y
不能是Number
或BigInt
x
和y
类型一致x
是undefined
,返回true
x
是null
,返回true
x
是String
,x
和y
是完全相同的代码单元序列(在相应的索引处具有相同的长度和相同的代码单位),返回true
,否则返回false
x
是Boolean
,x
和y
都是true
或者都是false
,则返回true
,否则返回false
x
是Symbol
,x
和y
是相同的Symbol
值,返回true
,否则返回false
x
和y
是相同的对象 值,返回true
,否则返回false
抽象关系比较
比较
x < y
(其中x
和y
是值)会产生true
,false
或undefined
(这表明至少一个操作数是NaN
)。除x和y外,该算法还使用名为LeftFirst
的布尔标志作为参数。该标志用于控制对x
和y
执行具有潜在可见副作用的操作的顺序。LeftFirst
默认为true
。LeftFirst
为true
,px
,执行ToPrimitive(x, hint Number)(如果是Object
,默认先执行valueOf()
,不满足再执行toString()
)py
,执行ToPrimitive(y, hint Number)(如果是Object
,默认先执行valueOf()
,不满足再执行toString()
)py
,执行ToPrimitive(y, hint Number)(如果是Object
,默认先执行valueOf()
,不满足再执行toString()
)px
,执行ToPrimitive(x, hint Number)(如果是Object
,默认先执行valueOf()
,不满足再执行toString()
)px
和py
都是String
,true
,则返回fasle
(px包含py)true
,则返回true
(py包含px)px
和py
不具有 前缀(必须是前缀) 包含关系,则定义过程变量k
为最小非负整数,以便px
内索引k
处的码点与py
内索引k
处的码点不同。(必须有一个k
,因为两个字符串都不是另一个的前缀)m
为整数,该整数是px
以内的索引k
处的码点的数值n
为整数,该整数是py
以内的索引k
处的码点的数值m
<n
,返回true
,否则返回false
(这里主要比较的是字符串在Unicode码表中的码点数值)px
是BigInt
,py
是String
,ny
,调用StringToBigInt(py)将结果赋值给ny
ny
为NaN
,返回undefined
py
是BigInt
,px
是String
,nx
,调用StringToBigInt(px)将结果赋值给ny
nx
为NaN
,返回undefined
nx
,执行ToNumeric(px) 将结果赋值给nx
(px
和py
此时已经都是primitive(原始,这里应该都是 数值)值了,顺序不重要)ny
,执行ToNumeric(py) 将结果赋值给ny
nx
和ny
类型一致,执行对应类型的lessThan(nx, ny)
(Number::lessThan (nx, py),BigInt::lessThan(nx, py))方法nx
是BigInt
类型并且ny
是Number
类型,或者两者类型对调nx
或ny
是NaN
,返回undefined
nx
是-Infinity
或ny
是+Infinity
,返回true
nx
是+Infinity
或ny
是-Infinity
,返回false
nx
的数学值比ny
的数学值小,返回true
,否则返回false
抽象相等 ==
日常使用的
==
。x
和y
的类型一致,则返回x
===y
的结果。(即类型一致,默认采用全等比较)x
是null
同时y
是undefined
,返回true
x
是undefined
同时y
是null
,返回true
x
是Number
类型,y
是String
类型,将y
转为Number
然后继续比较x
是String
类型,y
是Number
类型,将x
转为Number
然后继续比较x
是BigInt
类型,y
是String
类型,n
,执行StringToBigInt(y)将结果赋值给n
n
是NaN
,返回false
x
==n
的结果x
是String
类型,y
是BigInt
类型,返回y
==x
的结果(其实就是位置对调然后重复上一步)x
是Boolean
类型,将x
转为Number
类型,然后比较转为Number
类型后的值与y
比较结果y
是Boolean
类型,将y
转为Number
类型,然后比较转为Number
类型后的值与x
比较结果x
是String
,Number
,BigInt
,Symbol
类型,y
是Object
类型,先将y
转为原始类型,然后再比较(执行 ToPrimitive(y))x
是Object
类型,y
是String
,Number
,BigInt
,Symbol
类型,先将x
转为原始类型,然后再比较(执行 ToPrimitive(x))x
是BigInt
类型,y
是Number
类型,或者x
是Number
类型,y
是BigInt
类型x
或y
有一个是NaN
,+Infinity
,-Infinity
,返回false
(事实上,BigInt
不支持这三个值)x
的数学值和y
的数学值相等,返回true
,否则返回false
false
严格相等 ===
就是日常使用的
===
全等。false
x
是不是Number
或BigInt
,然后对x
和y
执行equal
(BigInt::equal ( x, y ),Number::equal ( x, y )操作比较回归开头代码
首先是字符串的比较,我知道了它会先判断是不是前缀,否则直接开始比较相同下标对应的字符在Unicode中的码点大小:
接着是全等,这个其实不难,既要判断类型又要判断值是不是都一样:
容易困惑的在于
NaN
,Symbol
:NaN
属于Number
类型,适用于Number::equal ( x, y ),不论谁是NaN
,都返回false
!!!Object
,它最终比较的是地址内存值Symbol
,有点Object
的意思。接下来是普通
==
,它只要求值相等不强调类型:最后,则是其它的大小比较了:
Boolean
会被转为Number
来比较NaN > 0
会执行Number::lessThan (nx, py),有NaN
,根据规范应该返回undefined
,不过浏览器把它实现成了false
!!!Symbol() > 0
会尝试把Symbol
转为Number
,可是根据类型转换规则,会报类型错误{} < {}
和{} > {}
都会尝试转为原始值在进行比较,可惜,它们最终都会转为"[object Object]"
,两个最终字符串相同,所以只能是false
!!!额外补充Object.is
如果仔细看内容的话就知道为什么了。根本在于
Object.is
内部使用的是::sameValue ( x, y )
算法,而严格相等使用的是::equal ( x, y )
算法!所以两者在
NaN
以及+0
,-0
的比较上不同The text was updated successfully, but these errors were encountered: