JavaScript里值比较的方法
JavaScript里值比较的方法
参考资料
Object.is
和 == 与 === 不同
- == 运算符会对它两边的操作数做隐式的类型转换
- === 也不会对操作数进行类型转换,但是它会把
-0
和+0
这两个数值视为相同的,还会把两个 NAN 看成是不相等的。
+0 === -0 // true
-0 === 0 // true
+0 === 0 // true
Object.is(-0, +0) // false
Object.is(+0, 0) // true
Object.is(-0, 0) // false
NaN === NaN // false
Object.is(NaN, NaN) // true
这里,number 类型的数据有几种特殊的数值:
- Number.NEGATIVE_INFINITY === -Infinity // true
- Number.POSITIVE_INFINITY === Infinity // true
- 21/0 === Infinity // true
- -21/0 == -Infinity // true
- 0/0 // NaN
Object.is 比 === 更严格。
隐式的类型转换
原始类型(Undefined、Null、Boolean、Number和String) + 对象类型(Object)
null 和 undefined
有一个传闻:
假如你打算把一个变量赋予对象类型的值,但是现在还没有赋值,那么你可以用null表示此时的状态(证据之一就是typeof null 的结果是'object');相反,假如你打算把一个变量赋予原始类型的值,但是现在还没有赋值,那么你可以用undefined表示此时的状态。
typeof null // object
typeof undefined // undefined
这里有一个图大概能表述清楚,几种类型相互的转换关系
几个概念
- ToPrimitive:将操作数转为原始类型的值。
- ToNumber:将操作数转
- 类型的值都有一种向数字类型转化的趋势,底层就是依靠数值的比较
ToPrimitive
JavaScript引擎内部的抽象操作ToPrimitive()
有着这样的签名:
ToPrimitive(input, PreferredType?)
可选参数PreferredType可以是Number
或者String,
它只代表了一个转换的偏好,转换结果不一定必须是这个参数所指的类型,但转换结果一定是一个原始值.如果PreferredType被标志为Number,则会进行下面的操作来转换输入的值 (§9.1):
- 如果输入的值已经是个原始值,则直接返回它.
- 否则,如果输入的值是一个对象.则调用该对象的
valueOf()方法
.如果valueOf()方法
的返回值是一个原始值,则返回这个原始值. - 否则,调用这个对象的
toString()方法
.如果toString()
方法的返回值是一个原始值,则返回这个原始值. - 否则,抛出
TypeError异常
.
如果PreferredType被标志为``String
,则转换操作的第二步和第三步的顺序会调换.如果没有PreferredType这个参数,则PreferredType的值会按照这样的规则来自动设置:``Date类型的对象会被设置为String,其它类型的值会被设置为``Number
.
ToNumber
下面的表格解释了ToNumber()是如何将原始值转换成数字的
(§9.3).
参数 | 结果 |
---|---|
undefined |
NaN |
null |
+0 |
布尔值 | true被转换为``1 ,false转换为``+0 |
数字 | 无需转换 |
字符串 | 由字符串解析为数字.例如,"324"被转换为``324 |
如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, Number)将该对象转换为原始值,然后在调用T
oNumber()将这个原始值转换为数字.
下面的表格解释了ToNumber()是如何将原始值转换成数字的
参数 | 结果 |
---|---|
undefined |
NaN |
null |
+0 |
布尔值 | true被转换为``1 ,false转换为``+0 |
数字 | 无需转换 |
字符串 | 由字符串解析为数字.例如,"324"被转换为``324 |
如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, Number)将该对象转换为原始值,然后在调用T
oNumber()将这个原始值转换为数字.
toString
通过toString()将值转换为字符串
下面的表格解释了ToString()是如何将原始值转换成字符串的
(§9.8).
参数 | 结果 |
---|---|
undefined |
"undefined" |
null |
"null" |
布尔值 | "true" 或者 "false" |
数字 | 数字作为字符串,比如. "1.765" |
字符串 | 无需转换 |
如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, String)将该对象转换为原始值,然后再调用ToString(),将这个原始值转换为字符串.
valueOf
每个JavaScript固有对象的 valueOf 方法定义不同。
对象 | 返回值 |
---|---|
Array | 数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。 |
Boolean | Boolean 值。 |
Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。 |
Function | 函数本身。 |
Number | 数字值。 |
Object | 对象本身。这是默认情况。 |
String | 字符串值。 |
Math 和 Error 对象没有 valueOf 方法。
例子
{} == null?
ToPrimitive({}) => {}.valueOf() => {}.toString() => [object Object] => Number( [object Object] ) => NaN
null => Number(null) => 0
{} == null // false
{} + {} ?
ToPrimitive({}) => {}.valueOf() => {}.toString() => [object Object]
{} + {} // [object Object][object Object]
[''] == '' ?
ToPrimitive(['']) => [''].valueOf() => [''].toString() => '' => Number( '' ) => 0
'' => Number('') => 0
[''] == '' // true