犀牛書第四章主要講解了關於 JavaScript 中的 表達式 和 運算符。數組
本篇主要說如下 運算符 和 運算符相關的類型轉換 部分。函數
數據類型和類型之間的轉換規則請查看:post
eval('some code');
var geval = eval;
geval('some code');
'use strict';
eval('some code');
複製代碼
關係運算符 老是會返回一個布爾值。學習
== 運算符在進行判斷時會對操做數進行隱式類型轉換,按照如下步驟進行判斷ui
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
複製代碼
比較運算符(>, <, >=, <=)在進行運算時會按照如下規則進行判斷:編碼
<= 實際爲 不大於(a >= b ==> !(a < b),排除 NaN)、>= 實際爲 不小於(a <= b ==> !(a > b),排除 NaN),不依賴與相等運算符的比較規則。spa
+ 運算符 依賴於操做數,若是一個操做數爲字符串或者轉換爲原始值後爲字符串,會將另外一個操做數做爲字符串進行拼接。不然將進行數值加法計算。code
++ -- 運算符依賴於操做數的位置,運算符在操做數前時爲 前增量,返回計算後的值,運算符在操做數後是爲 後增量,返回計算前的值。cdn
++ -- 運算符的操做數 只會被轉換爲數字。對象
位運算符會 將操做數轉換爲數字,NaN、Infinity、-Infinity 會被轉換爲 0。
位運算符針對 32 位整形,會 忽略小數點和超出 32 位的二進制位。
直接 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 上的運算符優先級表格
運算符的 優先級決定了在複雜表達式運算過程當中,運算的前後順序。
從上往下優先級越低,最高的是括號,而後是屬性訪問、對象建立等,最後是賦值運算符、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、賦值運算符、++、--。