JS中的一元操作符


  • 表達式
  • 一元操作符
  • 優先級
  • 結合性
  • 運算順序

 

表達式是什么?


就是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永遠是從左向右運行;

  1. 首先JS會先計算b,得到b;
  2. 再計算a++,得到結果1,但是這個過程結束后a的值變成了2;
  3. 第三步計算后面的a,得到2;
  4. 第四步計算1+2,得到3;
  5. 把3賦值給b;

 

var a = 1;
b = a ++ + ++ a;  // 4
  1. 先算a++,得到1,這時a的值變成了2;
  2. 再算++a,得到3;
  3. 1+3得到4;
  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: 用來遍歷對象;

 

 

 

 

 

————整理自沙翼老師的前端音頻教程#陪你讀書#(喜馬拉雅)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM