- 表達式
- 一元操作符
- 優先級
- 結合性
- 運算順序
表達式是什么?
就是JS 中的一個短語,解釋器遇到這個短語以后會把對它進行計算,得到一個結果參與運算,我們把這種要參與到運算中的各種各樣的短語稱為表達式。實際上,JS 的代碼就是由表達式和操作符構成的,可以說除了操作符以外的基本都是表達式。
例如:a + 1;這行代碼中,加號左邊的a和右邊的1都是表達式,而加號是操作符。
表達式的分類(大概可以分成6類)
1, 原始表達式(4種):常量、變量、直接量、關鍵字
- 常量:那些不會改變的量。其實在JS中大部分東西都是可以改變的,如果我們想要讓一個東西保持不變,例如關於圓的計算中的PI,可以把它設成常量;常量通常會使用大寫字母,或者用下划線來表示;
const PI = 3.14; PI = 3; // 修改常量的值會報錯
- 變量:可以隨時發生變化;(這個與JS的基礎數據類型不可變不是一碼事)
var a = 1; a = 2; // 給變量a重新賦值
- 直接量:數字、字符串、正則表達式;如:1 + 1; 這里1就是一個直接量;
- 關鍵字:所有關鍵字都是表達式;
2, 初始化表達式:
- var obj = {name: ‘suki};
- var arr = [1, 2, 3];
3, 函數定義表達式: function foo() {}
4, 函數調用表達式:foo();
5, 屬性訪問表達式:obj.name; obj[name];
6, 對象創建表達式: new Foo();
一元操作符
只可以操作一個表達式的符號,共有9個;
一元加
- 對數字進行一元加操作,結果返回數字本身,要注意對負數進行一元加操作結果還是負數啦,不要以為會得到整數;
- 對布爾類型進行一元加操作,true的話返回1,false返回0;
- 對null進行一元加操作,返0;
- 對undefined進行一元加操作,返回NaN;
- 對字符串進行一元加操作,有兩種結果,如果字符串由純數字構成的話,返回1,如果不是則返回NaN;
- 對對象進行一元加操作,也有兩種結果,一是返回數字,二是返回NaN;操作過程中首先會調用valueOf方法,如果得不到數字結果,就調用toString方法,再對得到的字符串進行一元加操作;
用途:將表達式轉換成數字;
一元減
- 對數字使用:返回數字的負數;
- 對其他數據類型使用:首先嘗試把表達式轉換成數字,再取負數;
var b = false; -b; // -0
首先將false轉換成數字得到0,然后取0的負數得到-0,在 JS 中 +0 === -0; // true;
前置遞增、遞減操作符
解釋器首先會對表達式進行加一或減一的操作,然后再讓表達式參與到后面的運算中;
var num1 = 2; var num2 = 20; --num 1 + num2; // 1 + 20
后置遞增、遞減操作符
先讓表達式參與運算,再對表達式進行加一或減一的操作;平常后置遞增、遞減操作符用得比較多一點;
var num1 = 2; var num2 = 20; num 1-- + num2; // 2 + 20 num1; // 1
var age = 21; ++age; // 22 // 如果操作數是數字的話,這兩者寫法是一樣的 age = age + 1; // 22
但如果涉及到字符串表達式,情況就不一樣了
var name = ‘suki’; ++name; // NaN // 只要有一個操作數是字符串,加號就會變成字符串連接符 name = name + 1; // ‘suki1’
優先級
就像在數學表達式里,先算乘除再算加減, 因為乘除的優先級比加減高;
屬性訪問 > 一元操作符 > 乘除 > 加減 > 比較 > 相等 > 與運算 > 或運算 > 三目運算 > 賦值運算
不用記那么多,只要記住下面三點就好了:
- 屬性訪問表達式擁有最高優先級;
- 賦值運算(=)具有最低優先級(其實比等號更低的是逗號,但平常逗號不會參與到運算中);
- 在所有運算符中,一元運算符擁有最高優先級;
var a = 3; ++a == 3; // false;
因為相等(==)的優先級比遞增操作符(一元操作符)要低,所以會先計算++a,得到4,再計算4==3,返回false;
結合性
當一行代碼中存在多個運算符,而且這些運算符的優先級相等時,那要怎么計算?這就引出了結合性的問題了;
- 左結合
- 右結合
其實就是從左邊開始算還是從右邊開始算的問題;
所有一元操作符、三目運算符和賦值運算符都是右結合,其他的操作符都是左結合;
!a++;
如果是從左往右運算,!a先得到一個布爾類型,(!a)++最后得到一個數字類型;
如果是從右往左運算,a++先得到一個數字類型,!(a++)后得到一個布爾類型;
邏輯非(!)和遞增操作符(++)都是一元運算符,當兩個一元運算符同時存在於一行代碼中時,從右往左運算,所以最后會得到一個布爾類型的結果;
x = a ? b : c ? d : e ? f : g;
三目運算符也是右結合的,從右向左運算,相當於
x = a ? b : (c ? d : (e ? f : g));
var a = b = c = d;
連等賦值,也是從右向左運算,先取d的值,把它賦給c,再把c的值賦給b,再把b的值賦給a;
運算順序
當表達式里還包含表達式時怎么處理?
a = 1; b = a +++ a; console.log(a, b); // 2 3
這種情況JS永遠是從左向右運行;
- 首先JS會先計算b,得到b;
- 再計算a++,得到結果1,但是這個過程結束后a的值變成了2;
- 第三步計算后面的a,得到2;
- 第四步計算1+2,得到3;
- 把3賦值給b;
var a = 1; b = a ++ + ++ a; // 4
- 先算a++,得到1,這時a的值變成了2;
- 再算++a,得到3;
- 1+3得到4;
- 把4賦值給b;
一元加、一元減、遞增操作符、遞減操作符
這四個操作符對所有數據類型都有效;
- 一元加、一元減其實就是將任何數據類型轉換成數字類型(因為所有數據類型都可以被轉換成數字);
- 遞增操作符、遞減操作符把任何數據類型先轉換成數字,然后再進行加一或減一的操作;
但對小數進行遞減操作的時候得到的結果可能會與想象中的不一樣
var a = 1.1; --a; // 0.10000000000000009
所以一定要先把小數轉換成整數再計算,得到結果再轉換回小數;
按位非
只需知道一點,對一個數字進行按位非運算,就是取負值再減一;例如對10進行按位非運算得到結果是-11;
按位與
可以用來判斷數字的奇偶性;
function even_or_odd(number) { return (number & 1) ? "Odd" : "Even"; }
- 奇數轉換成二進制最后一位是1,所以和1進行按位與運算會返回1;
- 偶數轉換成二進制最后一位是0,所以和1進行按位與運算會返回0;
邏輯非
把任何數據類型轉換成布爾類型,再取反;
字符形式的一元操作符
typeof: 可以用括號把它要操作的表達式括起來,但不要誤以為它是函數,括號只是方便讓人看出運算邏輯而已;
void: 無論表達式是什么,都是返回一個undefined;
delete: 用於刪除對象的屬性;
字符形式的二元操作符
instanceof: 用來判斷對象的構造函數,但用得不多;
in: 用來遍歷對象;
————整理自沙翼老師的前端音頻教程#陪你讀書#(喜馬拉雅)