JS隐式转换--宽松相等(==)

353 阅读3分钟

1.隐式转换规则

Standard ECMA-262 6th Edition 对宽松相等(==)的定义如下:

Abstract Equality Comparison
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

  • 若x与y的类型相同, 则返回x===y的结果
  • 若x=null,y=undefined,则return true。
  • 若x=undefined,y=null,则return true。
  • 若x的类型为Number,y的类型为String,则return x == ToNumber(y)的执行结果。
  • 若x的类型为String,y的类型为Number,则return ToNumber(x) == y的执行结果。
  • 若x的类型为Boolean, 则return ToNumber(x) == y的执行结果。
  • 若y的类型为Boolean, 则return x == ToNumber(y)的执行结果。
  • 若x的类型为String, Number或者Symboly,y的类型为 Object, 则 return x == ToPrimitive(y)的执行结果。
  • 若x的类型为Object,y的类型为String, Number, 或者Symbol, 则 return ToPrimitive(x) == y的执行结果。
  • 若以上都不满足则return false

2.各隐式装箱的定义

2.1 ToNumber(其他类型转换为数字)

参数类型 结果
Undefined NaN
Null 0
Bollean true => 1
fale => 0
Symbol Throw a TypeError exception
String 如果字符串能被解析为StringNumericLiteral(定义如下),则将字符串转换为相应的数字,否则ToNumber的结果为NaN
Object 1.先执行ToPrimitive操作,将object转换为基本类型
2.执行ToNumber操作

StringNumericLiteral :::
StrWhiteSpace
StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
StrWhiteSpace :::
StrWhiteSpaceChar StrWhiteSpaceopt
StrWhiteSpaceChar :::
WhiteSpace
LineTerminator
StrNumericLiteral ::::
StrDecimalLiteral
BinaryIntegerLiteral
OctalIntegerLiteral
HexIntegerLiteral
StrDecimalLiteral :::
StrUnsignedDecimalLiteral
+StrUnsignedDecimalLiteral
-StrUnsignedDecimalLiteral
StrUnsignedDecimalLiteral :::
Infinity
DecimalDigits . DecimalDigitsopt ExponentPartopt
. DecimalDigits ExponentPartopt DecimalDigits ExponentPartopt
DecimalDigits :::
DecimalDigit
DecimalDigits DecimalDigit
DecimalDigit ::: one of
0 1 2 3 4 5 6 7 8 9
ExponentPart :::
ExponentIndicator SignedInteger
ExponentIndicator ::: one of
e E
SignedInteger :::
DecimalDigits
+DecimalDigits
-DecimalDigits

2.2 ToPrimitive( input [, PreferredType] )

ToPrimitive根据PreferredType将input转换为primitive基本类型,在ES6中用户可自定义toPrimitive方法。

  • input(null,undefined,string,number,bool,Symbol)->直接返回input
  • input的类型为Date类型时(若用户没有改写toPrimitive)->PreferedType=string,则:
    a.调用input的toString方法,若result时primitive基本类型则返回result
    b.否则,调用input的valueOf方法,若result时primitive基本类型,则返回result
    c.否则,Throw a TypeError exception.
  • input为非Date的引用类型时(若用户没有改写toPrimitive)->PreferedType=number,则:
    a.调用input的valueOf方法,若result是primitive基本类型则返回result
    b.否则,调用input的toString方法,若result是primitive基本类型,则返回result
    c.否则,Throw a TypeError exception.

不同类型对象的valueOf()方法的返回值

对象 返回值
Array 返回数组对象本身。
Boolean 布尔值。
Date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认情况。
String 字符串值。
Math 和 Error 对象没有 valueOf 方法。

2.3 ToString(其他类型转为数字)

参数类型 结果
Undefined 'undefined'
Null 'null'
Bollean true =>'true'
fale =>'fale'
Symbol Throw a TypeError exception
Number NaN => 'NaN'
+0 or -0 => '0'
+∞ => Infinity
Object 1.先执行ToPrimitive操作,将object转换为基本类型
2.执行ToString操作
PS:
(1).""+value与String(value)都是运用内部函数toString将基本类型转为字符串的
(2).可通过Object.prototype.toString()来检测每个对象的类型,但需要以Function.prototype.call()或者Function.prototype.apply()的形式来调用,如:Object.prototype.toString.call(function(){})=>"[object Function]"

2.4 ToBoolean

参数类型 结果
Undefined false
Null false
String 空字符串 =》false,其他为true
Symbol true
Number +0, −0, or NaN => false,其他为true
Object true