一道面试题
最近看到一道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,运算顺序也一样,前面的可读性更好吧?