运算符优先级
本文不会具体到每个运算符的优先级比较,而是侧重于介绍运算符优先级在代码中的相关规则
var a = "a",
b = "b",
c = "c";
a && b || c; //"b"
a || b && c; //"a"
先来看上面的例子
首先JavaScript的默认执行顺序是从左到右的
那么按照顺序运行的话
运行的应该是(a&&b)||c和(a||b)&&c
返回的应该是"b"(a为true , a&&b返回"b" , "b"为true , "b"||c返回"b" )
和"c"(a为true , a||b返回"b" , "b"为true , "b"&&c返回"c")才对
(关于&&和||的规则不懂的可以看这JavaScript 学习笔记 之 强制类型转换 (二) 中 ||和&& 一节)
于是在这里就引入了一个运算符优先级的概念(本例中的&&优先级大于||,&&和||的优先级又大于?:(三元运算符)大于=运算符)
再来看看之前的例子(JavaScript 学习笔记 之 语句和表达式中 表达式行为 一节)
var a = 42;
var b = (a++, a);
b; //43
var a = 42;
var b = a++, a;
b; //42
这个例子中出现差异的原因在于","运算符在连接一系列语句的时候,优先级最低
短路
之前提到过的&&和||存在一个叫做"短路"的特性
对&&和||来说,如果从左边的操作数能得出结果,那么就可以忽略右边的操作数,这种执行最短路径的现象就是短路
比如 a&&b 如果a为false则返回a而忽略b
a||b 中如果a为true也会只返回a而忽略b
关联
如果多个相同优先级的运算符同时出现,该如何处理呢?
一般来说,运算符的关联不上从左到右就是从右到左,这取决于组合是从左开始还是从右开始
如果&&是左关联的话,a&&b&&c会被处理成(a&&b)&&c
如果&&是右关联的话,a&&b&&c会被处理成a&&(b&&c)
这里有个误解,不管是右关联还是左关联,a&&b&&c的严格执行顺序都是从左到右,先运行a,b然后是c
执行顺序和关联并不是一回事
关联只是决定组合的方向(也就是能用()括起来的方向)
var a={
name:"初始a"
}
var b=a;
a.son=a={name:"新的a"};
a;//{name: "新的a"}
b;//{name: "初始a", son: {…}}
来看看这个例子,首先=运算符是右关联性的运算符
因此a.son=a={..}实际上等同于 a.son =( a= {..} )
但是执行顺序依旧是 a.son , a 然后是{..}
因此执行a.son的时候a指向的是name值为初始a的那个对象
另一个右关联(组合)的运算符的例子是?:(三元运算符)
true ? false : true ? true : true; //false
//当?:为右结合运算符的时候
true ? false : (true ? true : true); //false
//当?:为左结合运算符的时候
(true ? false : true) ? true: true; //true