腦圖學習 JavaScript 之犀牛書【四 · 一】運算子、型別轉換

ZxBing0066發表於2019-10-31

介紹

犀牛書第四章主要講解了關於 JavaScript 中的 表示式運算子

本篇主要說以下 運算子運算子相關的型別轉換 部分。

資料型別和型別之間的轉換規則請檢視:

自我提問

  • ==、+、關係運算子等運算時怎麼進行型別轉換的?
  • eval 使用的幾種方式?
    eval('some code');
    
    var geval = eval;
    geval('some code');
    
    'use strict';
    eval('some code');
    複製程式碼
  • 運算子的優先順序和結合性?
  • 什麼是左值?

腦圖

腦圖學習 JavaScript 之犀牛書【四 · 一】運算子、型別轉換

關鍵知識點

關係運算子

關係運算子 總是會返回一個布林值

== 運算子的型別轉換規則

== 運算子在進行判斷時會對運算元進行隱式型別轉換,按照以下步驟進行判斷

  1. 運算元型別相同時,不進行型別轉換,套用 === 運算子的結果
  2. 運算元為 null 和 undefined 時,返回 true
  3. 運算元為數字和字串時,將字串轉換為數字後進行比較
  4. 其中一個運算元為布林值時,將布林值轉換為數字後進行比較
  5. 其中一個運算元為物件時,按照之前說過的物件到原始值的轉換規則
  6. 都不滿足,返回 false
1 == 2 // false
null == undefined // true
123 == '123' // true
true == '1' // true
({
    valueOf: () => {
        console.log('valueOf');
        return {};
    },
    toString: () => {
        console.log('toString');
        return '123';
    }
}) == 123; // valueOf toString true
({
    valueOf: () => {
        console.log('valueOf');
        return 123;
    },
    toString: () => {
        console.log('toString');
        return '123';
    }
}) == '123'; // valueOf true
NaN == NaN; // false
複製程式碼

比較運算子的轉換規則

比較運算子(>, <, >=, <=)在進行運算時會按照以下規則進行判斷:

  1. 運算元為物件時,物件會按照之前說過的物件到原始值的轉換規則進行轉換
  2. 其中一個運算元為 NaN 時,總是返回 false
  3. 運算元均為字串時,進行字母表比較(編碼比較)
  4. 有一個非字串時,運算元會轉換為數字進行比較

<= 實際為 不大於(a >= b ==> !(a < b),排除 NaN)、>= 實際為 不小於(a <= b ==> !(a > b),排除 NaN),不依賴與相等運算子的比較規則

+ 運算子

+ 運算子 依賴於運算元,如果一個運算元為字串或者轉換為原始值後為字串,會將另一個運算元作為字串進行拼接。否則將進行數值加法計算。

++ --

++ -- 運算子依賴於運算元的位置,運算子在運算元前時為 前增量返回計算後的值,運算子在運算元後是為 後增量返回計算前的值

++ -- 運算子的運算元 只會被轉換為數字

位運算子

位運算子會 將運算元轉換為數字NaN、Infinity、-Infinity 會被轉換為 0

位運算子針對 32 位整形,會 忽略小數點和超出 32 位的二進位制位

eval

直接 eval 會在呼叫它的上下文作用域下執行,會 影響到呼叫的作用域

間接 eval 會在 全域性上下文進行執行,不會影響呼叫的作用域。

嚴格模式下 eval 可以讀寫區域性變數但是不能新增區域性變數、函式

&& || ?:

&& 和 || 可用來進行 程式碼短路

?: 可 實現類似 if 的作用。

true && console.log(123); // 123
false && console.log(123); //
true || console.log(123); //
false || console.log(123); // 123

true ? console.log(123) : console.log(456); // 123
false ? console.log(123) : console.log(456); // 456
複製程式碼

運算子優先順序

這裡套用一下 MDN 上的運算子優先順序表格

腦圖學習 JavaScript 之犀牛書【四 · 一】運算子、型別轉換

運算子的 優先順序決定了在複雜表示式運算過程中,運算的先後順序

從上往下優先順序越低,最高的是括號,然後是屬性訪問、物件建立等,最後是賦值運算子、yield、逗號運算子。

a = 1 * 2 - 1
// 按照運算子的優先順序,會先計算 1 * 2 得出 2,然後計算 2 - 1 得出 1,然後將 1 賦值給 a
複製程式碼

運算子結合性

表格的第三行定義了列出了各運算子的結合性,可以看看 MDN 上關於結合性的定義,結合性決定了相同的運算子之間的計算順序

Associativity determines the way in which operators of the same precedence are parsed.

1 / 2 / 3 
// 按照 / 的結合性從左往右,等價於
(1 / 2) / 3

a = b = c
// 按照 = 的結合性從右往左,等價於
a = (b = c)
複製程式碼

運算子運算元個數

每個運算子所需要的的運算元個數不同,+ 運算子需要 1 個或 2 個運算元,?: 需要三個運算元,根據運算元的數量,可以將運算子分類成 一元運算子二元運算子三元運算子

運算順序

一個 複雜表示式的運算順序和運算子的優先順序、結合性相關。 而子表示式在計算中總是按照從左往右的順序計算表示式的。 具體看最下方。

運算元型別、結果型別

運算子對運算元進行計算時會 將運算元轉換為想要的型別(隱式型別轉換)。

左值

左值 指表示式 只能出現在賦值運算子的左側,包括變數、物件屬性、陣列元素。

關於左值概念提及的較少,具體解釋一下,左值和右值的區別,當一個變數、物件屬性、陣列元素出現在賦值運算子的左邊時,取的是他的左值,可以認為取出的是他的記憶體地址,而出現在右邊是取的是他的右值也就是他的實際值,可以使用 getter 試試,左值出現在左邊時,getter 不會被觸發,因為左值不關心他的實際值,只關心他的地址。

var a = {
	get b() {
		console.log('get');
		return 123;
    }
};
// get 被列印,取出右值
var c = a.b;

// get 未被列印,取出左值
a.b = 1;
複製程式碼

除了賦值運算子,還有 delete 運算子的運算元也是左值。

運算子的副作用

部分運算子帶有 副作用,如 delete、賦值運算子、++、--。

系列文章目錄

  1. 腦圖學習 JavaScript 之犀牛書【一】
  2. 腦圖學習 JavaScript 之犀牛書【二】詞法結構
  3. 腦圖學習 JavaScript 之犀牛書【三 · 一】資料型別
  4. 腦圖學習 JavaScript 之犀牛書【三 · 二】型別轉換、變數
  5. 腦圖學習 JavaScript 之犀牛書【四 · 一】運算子、型別轉換
  6. 腦圖學習 JavaScript 之犀牛書【四 · 二】表示式
  7. 腦圖學習 JavaScript 之犀牛書【五】語句

相關文章