一道面試題
最近看到一道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,運算順序也一樣,前面的可讀性更好吧?