Math.PI 相关表达式运算

一段不算太新,流传网络的代码:

 

var a = (++Math.PI); 
alert(a); //1
alert(Math.PI); //2

var b = (Math.PI++); 
alert(b); //3
alert(Math.PI); //4

var c = Math.PI = (++Math.PI); 
alert(c); //5
alert(Math.PI); //6


var d = Math.PI = (Math.PI++); 
alert(d); //7
alert(Math.PI); //8


var e = Math.PI = (Math.PI + 1);
alert(e); //9
alert(Math.PI); //10

 

 

Math.PI 在其他语言看来是系统一个常量,修改它的话编译都通不过,不过 javascript 具有很强的的容错性(包容性?),他是不会提醒你的,要搞懂这个不看规范是不行的。

 

分析

 

ECMAScript 262 :

 

PI

 

15.8.1.6 PI
The number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932.
This property has the attributes { DontEnum, DontDelete, ReadOnly }.


只有系统属性才会有 readonly ,我们定义的一般属性没法设置, 而 ReadOnly 应该相当于常量了吧 ?


ReadOnly


8.6.1 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”!)


看见一般情况下,readonly属性不可以改,但不报错,即赋值修改没用!也不意味着是常量 !


那么现在知道了 : 2,4,6,8,10 条代码 alert 都是 3.14 了。


另外 3 alert 也不用解释了,返回自增前结果,还是 3.14


那么 1 alert 难道还是 3.14 ,因为 PI readonly 无法改变 ?错误

 

 

自增运算符

 

 

涉及到 前缀自增运算符的返回值问题 :


11.4.4 Prefix Increment Operator The production UnaryExpression :


++ UnaryExpression is evaluated as follows:
1.    Evaluate UnaryExpression.

2.    Call    GetV alue(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    PutV alue(Result(1),    Result(4)).
6.    Return Result(4).


则可见返回的是  Result(4) Math.PI+1 ,而不是 第五步过后的 Result (1)


那么可见 1 alert 即为 Math.PI+1 = 4.14


 

 

赋值操作符

 

c,d,e 类似,= 操作符具有右结合性, 则申明初始化时,变量值为赋值表达式 (Math.PI = ++Math.PI) ,javascript 每个表达式都会返回一个值,这就涉及到了前句的表达式返回值是多少:


11.13.1    Simple Assignment ( = )


The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:
1.    Evaluate LeftHandSideExpression.

2.    Evaluate AssignmentExpression.

3.    Call    GetV alue(Result(2)).

4.    Call    PutV alue(Result(1),    Result(3)).
5.    Return Result(3).


前面自增规范可以得到 ++Math.PI 返回 4.14 为 Result 2,Result 3 ,同样的道理,第4步赋值后,返回的是赋值表达式右端的值 (++Math.PI),而不是左端的值 Math.PI ,则  (Math.PI = ++ Math.PI) 返回 ++Math.PI == 4.14 ,即连续赋值运算只返回最右边的值,而不管赋值中变量是否发生了变化。

 

 

 

 

 

 

 

 

你可能感兴趣的:(javascript)