Math.PI与++运算符

遇到一道题目:

var a = Math.PI++, b = ++Math.PI;
alert(a);
alert(b);
alert(Math.PI);

不加思索的写下:
3.14
4.14
3.14

后来经常提醒才想到Math.PI是常量,修改一个常量的值,会抛出错误。
而上面的操作中,b = ++Math.PI 可以理解为将Math.PI递增加1,并且赋值给变量 b;
这时候开始迟疑了:
在javascript中,给常量赋值是否会抛出错误呢?

复制代码执行一下,奇怪了,的确和我刚开始不加思索的结果那样,并没有抛出错误。
为什么在javascript中可以对常量进行这样的计算呢?

翻开ECMAScript规范

This property has the attributes { DontEnum, DontDelete, ReadOnly }

继续找到 ReadOnly 定义:

The property is a read-only property. Attempts by ECMAScript code to write to the property will be ignored. (Note, however, that in some cases the value of a property with the ReadOnly attribute may change over time because of actions taken by the host environment; therefore “ReadOnly” does not mean “constant and unchanging”!)

对该属性的写入将被忽略。
既然写入被忽略了,那 b = ++Math.PI 为什么是4.14而不是3.14呢。

继续翻看++运算符

The production UnaryExpression : ++ UnaryExpression is evaluated as follows:
1. Evaluate UnaryExpression.
2. Call GetValue(Result(1)).
3. Call ToNumber(Result(2)).
4. Add the value 1 to Result(3), using the same rules as for the + operator (see 11.6.3).
5. Call PutValue(Result(1), Result(4)).
6. Return Result(4).

看来并不是给 Math.PI 加上 1 再赋值给 b
而是在Result(3)上加上1,在第5步时,赋值给Math.PI(被忽略)
第6步,返回第4步的值。而不是返回Math.PI

现在,对于开头出现的结果不再感到迷惑了。
遇到问题,不仅仅是需要了解他的正确结果,最好是能了解正确结果是如何得来的。

发表评论

Your email is never shared. Required fields are marked *

*
*