一道面试题
最近看到一道js的面试题,内容如下:
var val = 'hhhh';
console.log('Value is ' + (val === 'hhhh')? 'Something': 'Nothing');
问:上边两行代码会打印什么内容呢?
A、 Value is Something;
B、Value is Nothing;
C、NaN;
D、其他内容。
*
*
*
*
*
各位看官可以先自己想思考30秒,想想答案是哪个。
*
*
*
*
在浏览器执行后,打印内容如下:
也就是说答案是 D。
答案就在标题里——是由于运算符的关系。
我们这里称 'Value is ' + (val === 'hhhh')? 'Something': 'Nothing' 为式1,
在 式1 里实际上包含了三种运算符,
分别是 二元加(+),小括号(()), 三元条件运算符(?:)。
由于小括号运算级最高,会优先运算小括号中的内容,所以解释器第一步会将 式1 转换为
'Value is ' + true? 'Something': 'Nothing' ,我们称为 式2 。
二元加运算符优先级又高于 三元条件运算符,所以 式2 会被转换为
'Value is true'? 'Something': 'Nothing' 我们称为 式3 。
到这里我想在座的各位都已经知道答案了,最终算式结果为 'Something'。
运算符优先级
面试题我们很清楚了,那么JS的运算符优先级又是怎么回事呢?
不仅在JS里,基本所有的开发语言中都有运算符和运算符的优先级的概念。运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。
下面的表将所有运算符按照优先级的不同从高到低排列,优先级越高越先执行。
优先级 |
运算类型 |
关联性 |
运算符 |
20 |
圆括号 |
n/a |
( … ) |
19 |
成员访问 |
从左到右 |
… . … |
|
需计算的成员访问 |
从左到右 |
… [ … ] |
|
new (带参数列表) |
n/a |
new … ( … ) |
|
函数调用 |
从左到右 |
… ( … ) |
18 |
new (无参数列表) |
从右到左 |
new … |
17 |
后置递增(运算符在后) |
n/a |
… ++ |
|
后置递减(运算符在后) |
|
… -- |
16 |
逻辑非 |
从右到左 |
! … |
|
按位非 |
|
~ … |
|
一元加法 |
|
+ … |
|
一元减法 |
|
- … |
|
前置递增 |
|
++ … |
|
前置递减 |
|
-- … |
|
typeof |
|
typeof … |
|
void |
|
void … |
|
delete |
|
delete … |
|
await |
|
await … |
15 |
幂 |
从右到左 |
… ** … |
14 |
乘法 |
从左到右 |
… * … |
|
除法 |
|
… / … |
|
取模 |
|
… % … |
13 |
加法 |
从左到右 |
… + … |
|
减法 |
|
… - … |
12 |
按位左移 |
从左到右 |
… << … |
|
按位右移 |
|
… >> … |
|
无符号右移 |
|
… >>> … |
11 |
小于 |
从左到右 |
… < … |
|
小于等于 |
|
… <= … |
|
大于 |
|
… > … |
|
大于等于 |
|
… >= … |
|
in |
|
… in … |
|
instanceof |
|
… instanceof … |
10 |
等号 |
从左到右 |
… == … |
|
非等号 |
|
… != … |
|
全等号 |
|
… === … |
|
非全等号 |
|
… !== … |
9 |
按位与 |
从左到右 |
… & … |
8 |
按位异或 |
从左到右 |
… ^ … |
7 |
按位或 |
从左到右 |
… | … |
6 |
逻辑与 |
从左到右 |
… && … |
5 |
逻辑或 |
从左到右 |
… || … |
4 |
条件运算符 |
从右到左 |
… ? … : … |
3 |
赋值 |
从右到左 |
… = … |
|
|
|
… += … |
|
|
|
… -= … |
|
|
|
… *= … |
|
|
|
… /= … |
|
|
|
… %= … |
|
|
|
… <<= … |
|
|
|
… >>= … |
|
|
|
… >>>= … |
|
|
|
… &= … |
|
|
|
… ^= … |
|
|
|
… |= … |
2 |
yield |
从右到左 |
yield … |
|
yield* |
|
yield* … |
1 |
展开运算符 |
n/a |
... … |
0 |
逗号 |
从左到右 |
… , … |
建议
运算符这么多,一不小心就用错了,怎么办?其实在JS运算过程中,和其他语言一样,我们最好直接带上括号,比如
var a = 1; a = (a + 100) >>(a+1);
和
var a = 1; a = a + 100>>a+1;
结果都是25,运算顺序也一样,前面的可读性更好吧?