如果您还没有检查过 JavaScript 测验 1、2、3 和 4,也请花点时间看看这些测验。每一个都建立在另一个之上,并且它们变得越来越困难。看看你是否真的了解你的 JavaScript 操作顺序。
var object1 = {
valueOf: function () {
return 10;
},
toString: function () {
return "object1";
}
};
var object2 = {
valueOf: function () {
return 20;
},
toString: function () {
return "object2";
}
};
var object3 = {
valueOf: function () {
return 30;
},
toString: function () {
return "object3";
}
};
var result = (object2, object1, object3) + object1 +-- object1;
alert(result);
问题 :警报的输出是什么,为什么?
*把你的答案写在一张纸上,然后阅读答案。*
回答 :
警报的输出是 49 。让我们来分析一下这个测验。在以下表达式中:
(object2, object1, object3)
为了知道这个表达式的结果,我们必须知道表达式如何与逗号运算符一起工作。如果我们有一个包含许多逗号运算符的表达式,那么这个表达式将被计算为最后提到的值。这意味着
(object2, object1, object3)
将被评估为
object3
。然后我们将有以下简化的表达式:
object3 + object1 +-- object1
在这个表达式中,我们有两个主要的运算符:
1. + 运算符。
2. -- 前缀运算符。
执行顺序如下:
1. -- 前缀运算符。
2. + 运算符。
要获取运算符优先级的完整列表,请查看 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence 。
执行顺序意味着表达式评估将从以下内容开始:
-- object1
-- 前缀运算符将应用于
object1
,这将导致调用
object1
的
valueOf
方法。这意味着结果将是 10 – 1 = 9。
然后通过将
object3 + object1
添加到先前的结果来继续执行评估,如下所示:
object3 + object1 + 9
现在,我们来到小测验最简单的部分,
object1
和
object3
的
valueOf
方法被调用,这意味着最终结果将是 30 + 10 + 9 = 49。
根据
Ecma-262规范的
原始加法规则如下,供大家参考:
“加法运算符执行字符串连接或数字加法。
产生式 AdditiveExpression : AdditiveExpression + MultiplicativeExpression 的计算如下:
1. 令 lref 为计算 AdditiveExpression 的结果。
2. 设 lval 为 GetValue(lref)。
3. 令 rref 为计算 MultiplicativeExpression 的结果。
4. 设 rval 为 GetValue(rref)。
5. 设 lprim 为 ToPrimitive(lval)。
6. 设 rprim 为 ToPrimitive(rval)。
7. 如果 Type(lprim) 是 String 或者 Type(rprim) 是 String,那么
A。返回连接 ToString(lprim) 后跟 ToString(rprim) 结果的字符串
8. 返回对 ToNumber(lprim) 和 ToNumber(rprim) 应用加法运算的结果。
”