Math.PI、前自增和后自增

  •   2009-07-08/16:30
  •   有这么一个题目,说bt其实也不bt,为了重点突出其中的意图,特意加上了括号:

    1. var a = (++Math.PI); 
    2. var b = (Math.PI++); 
    3. var c = Math.PI = (++Math.PI); 
    4. var d = Math.PI = (Math.PI++); 
    5. var e = Math.PI = (Math.PI + 1); 

     

     

    执行完后,a、b、c、d、e的值分别是什么呢?如果学校里学的C语言基础好的话,应该可以知道答案。你不妨先写下答案,我们再来看看ECMA的规范。

    在ECMA-262中,对于Math.PI的说明是这样的:

     

    引用内容:

     

    15.8.1.6

     

    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,那么你给Math.PI赋值是没有用的。

    再看看关于前自增(Prefix Increment):

     

    引用内容:

     

    11.4.4 Prefix Increment Operator

     

    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).

     

     

     

    注意,前自增返回的是第四步的结果,也就是自增1以后的值。因此,对于a来说,就是先取Math.PI的值,然后转化为Number,然后加1,返回的就是Math.PI的值加1以后的结果。因此,a是4.141592653589793.

    再看看关于后缀自增(Prefix Increment):

     

    引用内容:

     

    11.3.1 Postfix Increment Operator

     

    The production PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ is evaluated as follows:

    1. Evaluate LeftHandSideExpression.

    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(3).

     

     

     

    和上面的不同,返回第三步的结果,即没有自增之前的结果,因此返回3.141592653589793.

    再来看看两个连续赋值的三个表达式,由于赋值运算是右结合运算,因此这三个表达式相当于:

    1. var c = (Math.PI = (++Math.PI)); 
    2. var d = (Math.PI = (Math.PI++)); 
    3. var e = (Math.PI = (Math.PI + 1)); 

     

     

    而对于赋值运算,在ECMA-262中是这样描述的:

     

    引用内容:

     

    11.13.1 Simple Assignment ( = )

     

    The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:

    1. Evaluate LeftHandSideExpression.

    2. Evaluate AssignmentExpression.

    3. Call GetValue(Result(2)).

    4. Call PutValue(Result(1), Result(3)).

    5. Return Result(3).

     

     

     

    赋值后,返回第三步的结果,即语句右边的表达式的结果。因此,这里c、d、e的结果就很明显了:

    1. c = 4.141592653589793
    2. d = 3.141592653589793
    3. e = 4.141592653589793

    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多