一段不算太新,流传网络的代码:
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 ,即连续赋值运算只返回最右边的值,而不管赋值中变量是否发生了变化。
分享到:
相关推荐
优先级 : 由低至高 (同级间按在表达式中从左到右的顺序运算) + - * / ^(幂) %(求余) ㈡ 函数 rad(x)表示求x的弧度。如 rad(90) = pi/2 deg(x)表示求x的度数。如 deg(pi/4) = 45 ln(x) 表示求x...
log((5+5)^2)-3+pi需要写成Math.log(Math.pow(5+5,2))*Math.LOG10E-3+Math.PI才能用Eval进行计算,对于这一点我还没有想到理想的解决方案。好了,这不是本文正题,我们姑且放过。 博客园里曾经见人用过下面的代码,...
3.4 这是个巧妙的表达式: a ˆ= b ˆ= a ˆ= b 它不需要临时变量就可 以交换a 和b 的值。. . . . . . . . . . . . . . . . . . . . . . . . . 14 3.5 我可否用括号来强制执行我所需要的计算顺序? . . . . . . . . ....
7.3.4 算术运算和关系运算... 218 7.4 PHP主要语句... 219 7.4.1 赋值语句... 219 7.4.2 输入输出语句... 220 7.4.3 选择语句... 221 7.4.4 循环语句... 222 7.5 数组... 225 7.5.1 数组创建... 225 7.5.2 ...
数学表达式中的开平方、求绝对值、最大值、最小值等这些经常用到的运算,在Java 程序中该怎么解决呢?需要每次都自己编写程序呢还是有现成的功能供我们使用? 日常生活中更多信息是由字符组成的,若干个字符在计算机...
,>-数学函数(1-arg,2-arg,3-arg的大库--函数),即:sin,cos,斯特林数字,对数,反函数-常数(大库),即:pi,e,黄金比例-n-args函数,即:最大公约数-迭代求和和乘积运算符-微分和积分高灵活性:-用户定义...
评估器支持算术运算,自定义函数和参数。 它采用表达式的字符串表示形式,并将其转换为结构化的LINQ表达式实例,该实例可以轻松地编译为可执行委托。 与诸如NCalc之类的解释表达式求值器相反,编译表达式的执行速度...
使用fcal,您可以精确地执行基本的算术百分比运算。 它具有灵活的表达式解析器,具有大量内置单元,函数和常量。 灵感来自特征单位变数职能游乐场 , , 例子 const fcal = new Fcal ( ) ;// New variablefcal . ...
&= 运算符 对变量和表达式执行按位“与”运算,结果赋给变量。 && 运算符 对两个表达式执行逻辑连接运算。 * 运算符 将两个表达式的值相乘。 *= 运算符 将变量与表达式的值相乘,结果赋给变量。 + 运算符 将两个...
&= 运算符 对变量和表达式执行按位“与”运算,结果赋给变量。 && 运算符 对两个表达式执行逻辑连接运算。 * 运算符 将两个表达式的值相乘。 *= 运算符 将变量与表达式的值相乘,结果赋给变量。 + 运算符 将两个...
&= 运算符 对变量和表达式执行按位“与”运算,结果赋给变量。 && 运算符 对两个表达式执行逻辑连接运算。 * 运算符 将两个表达式的值相乘。 *= 运算符 将变量与表达式的值相乘,结果赋给变量。 + 运算符 将两个...
int realNumber=(int)(Math.random()*100)+1; int yourGuess=0; String str=JOptionPane.showInputDialog("输入您的猜测:"); yourGuess=Integer.parseInt(str); while(yourGuess!=realNumber) //循环条件 ...
实验二 数据类型、运算符和表达式 3 实验四 循环结构(1) 6 实验五 循环结构(2) 9 实验六 函数(1) 12 实验七 函数(2) 14 实验八 数组(1) 16 实验九 数组(2) 19 实验十 指 针 (1) 22 实验十一 指针(二) 24 实验十二 ...
条件是一个boolean类型的数据,如果条件结果为true,则执行表达式1的内容,并将表达式1的结果作为整体表达式的结果。如果条件为false,则执行表达式2的内容,并将表达式2的结果作为整体表达式的结果 ex: var age ...
o 6.13 考虑到有关空指针的所有这些困惑, 难道把要求它们内部表达都必须为 0 不是更简单吗? o 6.14 说真的, 真有机器用非零空指针吗, 或者不同类型用不同的表达? o 6.15 运行时的 ``空指针赋值" 错误是什么意思...
3.5 可否用显式括号来强制执行我所需要的计算顺序并控制相关的副作用?就算括号不行,操作符优先级是否能够控制计算顺序呢? 3.6 可是&&和||操作符呢?我看到过类似while((c=getchar())!=EOF&&c!='\n')的代码……...
3.7 是否可以安全地认为,一旦&&和||左边的表达式已经决定了整个表达式的结果,则右边的表达式不会被求值? 36 3.8 为什么表达式printf("%d %d", f1(), f2()); 先调用了f2?我觉得逗号表达式应该确保从左到右的...
当数据结构改变时,所有相关的处理过程都要进行相应的修改,每一种相对于老问题的新方法都要带来额外的开销,程序的可重用性差。 由于图形用户界面的应用,程序运行由顺序运行演变为事件驱动,使得软件使用起来...