4、{}+'a'<{}+'b'; [未解决]
(以下我要说的连我自己也弄不清楚是否正确)
要解释清楚这个表达式, 我们一步步来.
{}+'a' // ==> NaN
为什么一个空对象和一个字符串相加返回一个
首先看二元运算符+的解释:
1. Let lref be the result of evaluating AdditiveExpression.2. Let lval be GetValue(lref).3. Let rref be the result of evaluating MultiplicativeExpression.4. Let rval be GetValue(rref).5. Let lprim be ToPrimitive(lval).6. Let rprim be ToPrimitive(rval).7. If Type(lprim) is String or Type(rprim) is String, thena. Return the String that is the result of concatenating ToString( lprim) followed by ToString(rprim)8. Return the result of applying the addition operation to ToNumber( lprim) and ToNumber(rprim). See theNote below 11.6.3.NOTE 1No hint is provided in the calls to ToPrimitive in steps 5 and 6. All native ECMAScript objects except Dateobjects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if thehint String were given. Host objects may handle the absence of a hint in some other manner.NOTE 2Step 7 differs from step 3 of the comparison algorithm for the relational operators (11.8.5), by using thelogical-or operation instead of the logical-and operation.
我们直接跳到第5, 6步. 要对参与运算的参数都调用ToPrimitive()方法(而且根据NOTE 1, 这个方法是无参调用). 我们来看一下这个方法:
ToPrimitiveThe abstract operation ToPrimitive takes an input argument and an optional argument PreferredType. Theabstract operation ToPrimitive converts its input argument to a non-Object type. If an object is capable ofconverting to more than one primitive type, it may use the optional hint PreferredType to favour that type.
对于 Object来说
Object Return a default value for the Object. The default value of an object isretrieved by calling the [[DefaultValue]] internal method of the object,passing the optional hint PreferredType. The behaviour of the[[DefaultValue]] internal method is defined by this specification for all nativeECMAScript objects in 8.12.8.
就是要想知道ToPrimitive({})的值,请用DefaultValue内部方法转换之. 来看一下(我偷懒,没转换格式):
8.12.8 [[DefaultValue]] (hint)When the [[DefaultValue]] internal method of O is called with hint String, the following steps are taken:1.2.3.4.5.Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".If IsCallable(toString) is true then,a. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value andan empty argument list.b. If str is a primitive value, return str.Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".If IsCallable(valueOf) is true then,a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value andan empty argument list.b. If val is a primitive value, return val.Throw a TypeError exception.When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken:1.2.3.4.5.Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".If IsCallable(valueOf) is true then,a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value andan empty argument list.b. If val is a primitive value, return val.Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".If IsCallable(toString) is true then,a. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value andan empty argument list.b. If str is a primitive value, return str.Throw a TypeError exception.When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint wereNumber, unless O is a Date object (see 15.9.6), in which case it behaves as if the hint were String.The above specification of [[DefaultValue]] for native objects can return only primitive values. If a host objectimplements its own [[DefaultValue]] internal method, it must ensure that its [[DefaultValue]] internal methodcan return only primitive values.
简而言之,无参的DefaultValue会优先调用valueOf()方法, 看看是不是primitive value, 不是的话, 再调用toString()方法.
这个我们熟悉对吧.
({}).valueOf() // ==> Object {}
({}).toString() // ==> "[object Object]"
好了,我们终于把表达式{}+'a'进行了第一步转换:
({}) + 'a' // ==> "[object Object]a"
但 {}+'a'的值是多少呢? 是NaN, 为什么呢? 我也不知道