前面的話
javascript中的運算子大多由標點符號表示,少數由關鍵字表示,它們的語法言簡意賅,它們的數量卻著實不少。運算子始終都遵循著一些固定語法,只有瞭解並掌握這些內容,才能正確使用運算子。本文將主要介紹javascript運算子語法概述
運算元個數
javascript的運算子總共有46個,如果根據其運算元的個數進行分類,則大多數是二元運算子(binary operator),它們的運算元都是兩個,它們將兩個表示式合併成複雜表示式
1 + 2; true || false;
javascript中的一元運算子(unary operator)將一個表示式轉換為另一個稍複雜的表示式,主要包括以下9個:
++ -- - + ~ ! delete typeof void
a++; typeof true;
javascript只有一個三元運算子(ternary operator),是條件判斷運算子?:,它將三個表示式合併成一個表示式
2>1 ? 2 : 1;
優先順序
運算子優先順序控制著運算子的執行順序,優先順序高的運算子的執行總是先於優先順序運算子低的運算子
46個運算子總共分為14級的優先順序,從高到低依次是:
1 ++ -- - + ~ ! delete typeof void 2 * / % 3 + - 4 << >> >>> 5 < <= > >= instanceof in 6 == != === !== 7 & 8 ^ 9 | 10 && 11 || 12 ?: 13 = *= /= %= += -= &= ^= |= <<= >>= >>>= 14 ,
由這14級的運算子優先順序等級可以看出:
一元運算子 > 算術運算子 > 比較運算子 > 邏輯運算子 > 三元運算子 > 賦值運算子 > 逗號運算子
[注意]邏輯取反運算子屬於一元運算子,其優先順序最高
例子
!2<1&&4*3+1;
像上面這種情況就比較複雜,逐步來分解其運算順序
先計算一元運算子!,!2;//false
//於是表示式變為 false < 1 && 4*3 + 1;
計算算術運算子4*3+1;//13
//於是表示式變為 false < 1 && 13;
計算比較運算子<,false<1;//true
//於是表示式變為: true && 13;//13
可以使用圓括號來強行指定運算次序
2+3*5;//17 (2+3)*5;//25;
結合性
運算子具有兩種結合性,一種是從左向右結合,記號為L,一種是從右向左結合,記號為R。結合性指定了在多個具有同樣優先順序的運算子表示式中的運算順序
多數運算子都具有從左向右的結合性,只有一元運算子、條件運算子和賦值運算子具有從右向左的結合性
w = x + y + z; //等價於: w = ((x + y)+ z);
w = x = y = z; //等價於: w = (x = (y = z));
q = a ? b : c ? d : e ? f : g; //等價於: q = a ? b : (c ? d : (e ? f : g));
運算子的優先順序和結合性決定了它們在複雜表示式中的運算順序,但子表示式相互有影響時,順序會發生變化
例子
a = 1;
b = a++ + a-- * a++;
先分析該表示式中,根據優先順序的順序,分別運算遞增運算子、乘法運算子、加法運算子和賦值運算子
先計算第一個a++;//結果為1,a為2
//表示式變成 b = 1 + a-- * a++;
計算a--;//結果為2,a為1
//表示式變成 b = 1 + 2 * a++;
計算第二個a++;//結果為1,a為2
//表示式變成 b = 1 + 2 * 1;
所以,最終a = 2; b = 3;
a = 1; b = a++ + a-- * a++; console.log(a,b);//2 3
//類似地 a = 1; b = a-- * a++ + a++; console.log(a,b);//2,1
型別
一些運算子可以作用於任何資料型別,但仍然希望它們的運算元是指定型別的資料,並且大多數運算子返回一個特定型別的值,在下面的運算子規則表中,箭頭前為運算子運算元的型別,箭頭後為運算結果的型別
【左值】
左值(lvalue)是一個古老的術語,指表示式只能出現在運算子的左側
在javascript中,變數、物件屬性和陣列元素都是左值
遞增運算子++、遞減運算子--和賦值運算子的運算元型別是左值
var a = 3; a++;//3 3--;//報錯 ({}).a += '1';//'undefined1' 'test' -= 'test';//報錯
運算子規則表
運算子 操作 型別
++ 增量 lval->num -- 減量 lval->num - 求反 num->num + 轉換為數字 num->num ~ 按位求反 int->int ! 邏輯非 bool->bool delete 刪除屬性 lval->bool typeof 檢測型別 any->str void 返回undefined any->undef ****************************************************** * \ % 乘、除、求餘 num,num->num ****************************************************** + - 加、減 num,num->num + 字串連線 str,str->str ****************************************************** << 左移位 int,int->int >> 有符號右移位 int,int->int >>> 無符號右移位 int,int->int ****************************************************** < <= > >= 比較數字順序 num,num->bool < <= > >= 比較字母表順序 str,str->bool instanceof 測試物件類 obj,func->bool in 測試屬性 str,obj->bool ****************************************************** == 判斷相等 any,any->bool != 判斷不等 any,any->bool === 判斷恆等 any,any->bool !== 判斷非恆等 any,any->bool ****************************************************** & 按位與 int,int->int ****************************************************** ^ 按位異或 int,int->int ****************************************************** | 按位或 int,int->int ****************************************************** && 邏輯與 any,any->any ****************************************************** || 邏輯或 any,any->any ****************************************************** ?: 條件運算子 bool,any,any->any ****************************************************** = 賦值 lval,any->any *= /= %= += -= &= 運算且賦值 lval,any->any ^= |= <<= >>= >>>= ****************************************************** , 忽略第一個運算元, any,any->any 返回第二個運算元
參考資料
【1】 阮一峰Javascript標準參考教程——運算子 http://javascript.ruanyifeng.com/grammar/operator.html#toc29
【2】《javascript權威指南(第6版)》第4章 表示式和運算子