作者回复: 加分加分。呵呵~ ^^.
作者回复: 关键确实就在“对象属性存取这个行为本身”。
原始类型(中的值类型)的对象属性存取行为,例如“`true.toString`”会发生什么呢?它仍然是一次有效的属性存取,但它的结果(Result)并不会被立即求值。之前我们说过了,必须等到决定它是作为rhs/lhs之后,才能确定它是用来“求值”,还是只是“作为一个引用”,对不对?
那么,当得到操作`true.toString`的结果(Result)之后,在决定下一个可能的操作之前,它是一个什么状态呢?——这种情况下,它是作为一个“引用(规范类型)”来传递的。考虑到“引用(规范类型)”作为一个原始语言(例如C)中的结构/记录类型,那么它的ref.base域存放的,将是“值true”,而ref.name域中存放的,将是属性名“toString”。
所以你看,在这个阶段中,“包装(boxing)”这个行其实并没有发生。true还是true值,并没有“变成”Object(true),对不对?
所以说,确实存在一个“将对象属性存取这个行为(的结果)——作为一个整体”的阶段,这个存取行为并没有发生包装。但是,如果如下发生后一步的行为(也就是“作为整体来处理的过程中),那么,“包装”就会发生了。例如,GetValue(ref),那么就会先将ref.base中的值转换成对象;又例如,true.toString(),就会先将ref.true转换为对象然后作为this值传入toString()。
所以,“包装(亦即是‘转换为对象’)”这个行为,其实是发生在`GetValue()这个内部操作`或`()这个运算符`等等这样的运算过程中的。
所以回到最开始的,总之,“对象属性存取”这个行为本身,就是还没有触发“包装”。但它得到了包装要用的材料,亦即是ref.base和ref.name,不过还得需要“下一步”的具体操作,才能决定“包装是否会发生”。
作者回复: 题二其实是没有标准答案的。不过多做一点提示,就是+/-其实也是一正值和负值运算符,不一定非得当成加减号来用。正值和负值运算符一样也会导致类型转换。
作者回复: 第2题你的理解是对的,不过表达式可以再简一些。^^.
关于第一个问题,思考方向不是GetValue,而是toPrimitive。还有,它的结果不是[],它的求值结果是0。
作者回复: 第1个问题, 这样解释是不对的。[[DefaultValue]]是用在那些值类型的包装对象上的,例如5和new Number(5)之间的关系。而preferredType是另外一个问题,涉及JavaScript对“预期转换目标类型”的管理,不同的运算之间还不同(但都与具体的运算操作有关),与当前这个问题却没有太大的关系。
第2个问题的意思,是如何使一个表达式里面只出现“+-*/”和"[]",并且表达式还可以通过语法检测并计算求值。