官术网_书友最值得收藏!

3.5 運算符

3.5.1 算術運算符

1. 加法(+)、減法(-)、乘法(*)、除法(/)
  • 加法(+)運算符對操作數進行求和,也可用來連接兩個字符串。
  • 減法(-)運算符對操作數進行求差。
  • 乘法(*)運算符對操作數進行求積。
  • 加法(+)運算符對操作數進行求商。

語法:

      js expr1 + expr2; expr1 - expr2; expr1 * expr2; expr1 / expr2;

示例代碼:

當加法(+)運算符用來連接字符串時,JavaScript會將操作數進行隱式類型轉換后,再進行連接,示例如下。

2. 冪(**)

對被操作數進行乘方運算。

語法:js expr1 ** expr2; expr1為底數,expr2為指數。

示例代碼:

3. 取模(%)

返回第一個操作數除以第二個操作數的余數。

語法:

      expr1 % expr2;

示例代碼:

4. 一元正(+)

對操作數進行取值操作并返回,如果操作數不是Number類型,會將其轉化為Number類型,示例如下。

5. 一元反(-)

用來對操作數進行取反操作,示例如下。

6. 遞增(++)、遞減(--)

遞增(++)運算符將操作數+1后返回一個數值,遞減(--)運算符將操作數-1后返回一個數值。

語法:

      expr++;
      ++expr;

expr--; --expr;

示例代碼:

      ```js let foo = 1, let baz = 1;

// 先取值再計算 foo++; // -> 1 baz--; // -> 1
console.log(foo,baz); // > 2,0 ```

上述代碼中,定義了兩個變量foo和baz,并賦值為1,之后分別對foo和baz進行遞增和遞減操作,此時返回值均為1,這是因為遞增和遞減運算符兩種使用方式的返回值不同,具體如下。

  • 位于被操作數之后,返回遞增(減)前的數值。
  • 位于被操作數之前,返回遞增(減)后的數值。

示例代碼:

3.5.2 邏輯運算符

1. 邏輯與(&&)

邏輯與(&&)會在遇到能夠被轉化為false的操作數后返回該操作數,如果沒有,則返回最后一個操作數。

語法:

      expr1 && expr2;

示例代碼:

2. 邏輯或(||)

邏輯或(||)會在遇到能夠被轉化為true的操作數后返回該操作數,如果沒有,則返回最后一個操作數。

語法:

      js expr1 || expr2;

示例代碼:

利用邏輯與(&&)和邏輯或(||)的這個特性,可以方便地做短路運算,以精簡代碼,示例如下。

      function foo(name){
        return name || '';
      }
3. 邏輯非(!)

如果操作數能夠被轉化為true,則邏輯非(!)返回false;如果操作數能夠被轉化為false,則邏輯非(!)返回true。

語法:

      1expr;

示例代碼:

有時,你可能會看到!!的用法,!!相當于使用Boolean進行類型轉換,但在if語句中,!!是不必要的,因為if語句本身會對其中的表達式進行Boolean操作,使用!!反而會增加額外的性能消耗,示例如下。

      if(expr){ // 相當于 Boolean(expr)

}
// 不推薦的方式 if(!!expr){ // 相當于 Boolean(Boolean(expr))
}

3.5.3 比較運算符

比較運算符返回一個布爾值,表示兩個操作數的比較結果。

1. 大于(>)、小于(<)、大于或等于(>=)、小于或等于(< =)

比較運算符在比較expr1和expr2時,如果expr1和expr2類型不同,則將它們轉化成字符串、數字或布爾值進行比較,具體如下。

  • 大于(>):expr1大于expr2時,返回true。
  • 小于(<):expr1小于expr2時,返回true。
  • 大于或等于(>=):expr1大于或等于expr2時,返回true。
  • 小于或等于(<=):expr1小于或等于expr2時,返回true。

語法:

      expr1 > expr2;
      expr1 < expr2;
      expr1 >= expr2;
      expr1 <= expr2;

示例代碼:

2. 相等(==)、不相等(!=)

相等(==)和不相等(!=)會將兩個操作數轉換類型后進行比較。

語法:

      js expr1 == expr2; expr1 != expr2;

示例代碼:

3. 嚴格相等(===)、嚴格不等(!==)

嚴格相等(===)和嚴格不等(!==)直接比較兩個操作數,不進行類型轉換。

語法:

      expr1 === expr2;
      expr1 !== expr2;

示例代碼:

3.5.4 三元運算符

三元運算符對第一個表達式進行判斷,并根據其結果返回不同的表達式。

語法:

      js expr ? expr1 : expr2;

如果expr轉化為布爾值后為true,則返回expr1,否則返回expr2。

示例代碼:

      js true ? 1 : 2; // -> 1 false ? 1 : 2; // -> 2

3.5.5 賦值

賦值運算符將表達式右邊的值賦值給左邊的變量。

1. 賦值運算符

語法:

      expr1 = expr2;

示例代碼:

      let a = 1;
      console.log(a);  // > 1
      let b = a;
      console.log(b);  // > 1
2. 復合賦值

復合賦值是將某些運算符與賦值運算符組合使用,示例如下。

3. 解構賦值

解構賦值用于從數組或對象提取值,并保存到新的變量中。

數組的解構賦值,示例如下。

對象的解構賦值,示例如下。

字符串的解構賦值,示例如下。

3.5.6 位運算符

按位操作符(Bitwise operators)將其操作數(operands)當作32位的比特序列(由0和1組成),而不是十進制、十六進制或八進制數值。

例如,十進制數9,用二進制表示則為1001。按位操作符操作數字的二進制形式,但是返回值依然是標準的JavaScript數值。

表3-4總結了JavaScript中的按位操作符。

表3-4 位運算符

示例代碼:

位運算符也可與算術運算符組合使用。

3.5.7 異步操作符async function

在介紹async function前,我們先來講解ES6中出現的Promise,Promise是一個構造函數,其提供了異步編程的解決方案,以解決回調函數的問題,同時,其提供的all方法也為異步并發(例如并發請求)提供了處理機制。

Promise的用法如下。

ES8中引入了async function,用來簡化異步操作,示例如下。

如果async function內部有await命令,則需要等所有的await后面的Promise對象執行完,才會返回,示例如下。

上述代碼中的then方法也可以使用await來省略,await會在等待Promise對象執行完后,直接獲取resolve的值,示例如下。

await只能在async function定義的函數中使用,下面的示例創建了一個立即調用的函數表達式,關于立即調用函數表達式請參閱函數一章。

上面的示例中,最終執行的結果與直接調用then方法的結果有些不同,then方法的示例會在第1秒后輸出2,第2秒后輸出2,而await的示例會在第1秒后輸出2,之后才執行第二個await,間隔2秒后輸出2,因此,實際上是第3秒輸出的2,這是await的特點,也是async function/await致力于解決的痛點之一,將異步代碼同步化,降低異步編程的負擔。當然,如果你想讓上面的示例與調用then方法的結果相同,將其拆分成2個async function即可。

在await中,去掉了then方法那樣的鏈式操作,因此,也不能使用catch方法,如果要捕獲其中的錯誤,可以使用try…catch語句,示例如下。

此外,ES6也提供了Generator函數來處理異步編程,有了async function則不推薦再使用function*來處理異步問題。

Generator函數由function*聲明,在函數內部,不僅可以使用return返回,還可以使用yield返回,和await類似,yield只能在function*聲明的函數內部使用,示例如下。

Generator函數是可以嵌套的,示例如下。

現在,使用Generator函數運行上面的兩個示例。

相比于async function,function*的代碼更加煩瑣,畢竟Generator函數不是為異步而生的,Generator函數更適用于遍歷器(Iterator,參照本書相應章節)生成、狀態管理、無限序列等場景。

3.5.8 其他運算符

1. delete

從對象中刪除一個屬性,或從數組中移除一個元素,示例如下。

2. typeof與instanceof

可查看3.3.4小節。

3. void

void操作符對其后的表達式求值并返回undefined,一般用來替代undefined,示例如下。

4. new

new運算符通過一個構造函數創建一個實例,并返回這個實例。

其語法如下。

      new constructor[([arguments])]

其中,constructor是一個內置或自定義的構造函數,arguments為可選的入參,在constructor中被使用。

內置的構造函數有很多,例如,Number、String、Boolean、Date、Object、Function等,示例如下。

創建一個自定義的構造函數,示例如下。

      function People {};

// 通過 new 運算符創建一個實例 let p = new People();
5. in

返回一個布爾值,表示對象中是否包含該屬性,示例如下。

6. 逗號

逗號運算符順序執行表達式,并返回最后一個表達式,示例如下。

      1, 2, 3;  // -> 3
7. 括號()

用來提升運算優先級。

3.5.9 運算符優先級

運算符優先級規定了表達式執行運算時的順序——按照運算符的優先級從高到低執行。如下:先乘除后加減,表3-5列出了JavaScript中的運算符優先級。

表3-5 運算符優先級

續表

練習

  • 使用算術運算符。
  • 使用邏輯運算符。
  • 使用解構運算符。
  • 使用new運算符創建一個對象。
主站蜘蛛池模板: 从江县| 湖口县| 文化| 巴青县| 长海县| 福泉市| 循化| 四子王旗| 株洲市| 乐业县| 理塘县| 临沂市| 惠安县| 徐汇区| 常德市| 石城县| 邢台市| 东明县| 营山县| 微博| 杭州市| 广东省| 华亭县| 休宁县| 保山市| 北票市| 荔浦县| 司法| 宣汉县| 若尔盖县| 时尚| 三河市| 竹北市| 石渠县| 漾濞| 教育| 新津县| 那曲县| 凉山| 聊城市| 西林县|