精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

這些強大的 JS 操作符,你都知道嗎?

開發(fā) 前端
JavaScript 為我們提供了很多操作符,用于操作表達式。下面就來盤點一下 JavaScript 中那些強大的操作符!

大家好,我是 CUGGZ。

JavaScript 為我們提供了很多操作符,用于操作表達式。下面就來盤點一下 JavaScript 中那些強大的操作符!

一、一元操作符

操作符可以根據(jù)他們期待的操作符個數(shù)來分類,多數(shù)的JavaScript操作符都是二元操作符,二元操作符可以將兩個表達式合成一個更復(fù)雜的表達式。JavaScript也支持一元操作符,這些操作符可以將一個表達式轉(zhuǎn)化為另一個更復(fù)雜的表達式。同時,JavaScript中也有一個三元操作符,就是條件操作符(?:),它用于將三個表達式組成一個表達式。下面就先來看看一元操作符。

一元操作符具有以下特點:

  • 最簡單的操作符,用來操作一個表達式;
  • 具有高優(yōu)先級和右結(jié)合性;
  • 在必要時將操作數(shù)自動轉(zhuǎn)化為數(shù)值。

1. 遞增和遞減操作符(++ --)

遞增操作符顧名思義就是遞增其操作數(shù),遞減操作符就是遞減其操作數(shù)。它們都有兩個版本:

  • 前綴版(++i):操作符位于變量的前面,表示先遞增(遞減),后執(zhí)行語句;
  • 后綴版(i++):操作符位于變量的后面,表示先執(zhí)行語句,后遞增(遞減);

簡單看兩個例子:

// 前置遞增操作符:
let num1 = 1, num2 = 2;
console.log(++num1 + num2) // 4

// 后置遞增操作符:
let num1 = 1, num2 = 2;
console.log(num1++ + num2) // 3

可以看到,兩種類型的結(jié)果是不一樣的,原因就在于后置遞增遞減操作是在包含它們的語句被求值之后才執(zhí)行的。

這四個操作符可以作用于任何類型的數(shù)據(jù)。對于這些類型,JavaScript會將他們轉(zhuǎn)化為數(shù)值,再在這個數(shù)值上進行加一或減一操作。如果不能轉(zhuǎn)化為一個數(shù)字,那么遞增或遞減的結(jié)果就是NaN:

let str = "hello";
console.log(str++)  // NaN

遞增和遞減操作符主要用于for循環(huán)中控制計算器遞增或遞減。

2. 加和減操作符

加和減操作符既是一元操作符,也是二元操作符。這里我們先來看一元加和減操作符。

(1)一元加運算符(+)

一元加操作符會將其操作數(shù)轉(zhuǎn)化為數(shù)值,并返回轉(zhuǎn)化后的值。需要注意:

  • 如果操作數(shù)是數(shù)值,那它什么都不做;
  • 如果操作數(shù)不能轉(zhuǎn)化為數(shù)值,那么會返回NaN;
  • 由于BigInt值不能轉(zhuǎn)化為數(shù)值,因此這個操作符不能用于BigInt。
let a = -1;
let b = "hello";
let c = BigInt;
console.log(+a)  // -1
console.log(+b)  // NaN
console.log(+c)  // NaN

(2)一元減運算符(-)

一元減操作符和一元加操作符類似,會先將操作數(shù)轉(zhuǎn)化為數(shù)值,然后會改變結(jié)果的符號:

let a = -1;
let b = 2;
console.log(-a)  // 1
console.log(-b)  // -2

一元加和減操作符主要用于基本的算術(shù)運算,也可以用于數(shù)據(jù)類型的轉(zhuǎn)換,將不同類型的數(shù)據(jù)轉(zhuǎn)化為數(shù)字類型,像Number()方法一樣。

二、位操作符

現(xiàn)代計算機中數(shù)據(jù)都是以二進制的形式存儲的,即0、1兩種狀態(tài),計算機對二進制數(shù)據(jù)進行的運算加減乘除等都是叫位運算,即將符號位共同參與運算的運算。

JavaScript中所有的數(shù)字都是以IEEE 754 64位格式存儲,但是位操作并不直接應(yīng)用到64位,而是先將值轉(zhuǎn)化為32位整數(shù),再進行位操作。之后再把運算結(jié)果轉(zhuǎn)化為64位,所以我們只需要考慮32位整數(shù)即可。位操作是在數(shù)值的底層完成的,所以運算速度會相對于其他運算符快很多。

常見的位運算有以下幾種:

運算符

描述

運算規(guī)則

&`

兩個位都為1時,結(jié)果才為1

|

兩個位都為0時,結(jié)果才為0

^

異或

兩個位相同為0,相異為1

~

取反

0變1,1變0

<<

左移

各二進制位全部左移若干位,高位丟棄,低位補0

>>

右移

各二進制位全部右移若干位,正數(shù)左補0,負數(shù)左補1,右邊丟棄

在說這些操作符之前,先來看幾個相關(guān)的概念。計算機中的有符號數(shù)有三種表示方法,即原碼、反碼和補碼。三種表示方法均有符號位和數(shù)值位兩部分,符號位都是用0表示“正”,用1表示“負”,而數(shù)值位,三種表示方法各不相同。

(1)原碼

原碼就是一個數(shù)的二進制數(shù)。例如:10的原碼為0000 1010

(2)反碼

  • 正數(shù)的反碼與原碼相同,如:10    反碼為 0000 1010
  • 負數(shù)的反碼為除符號位,按位取反,即0變1,1變0。

例如,-10的反碼如下:

原碼:1000 1010
反碼:1111 0101

(3)補碼

  • 正數(shù)的補碼與原碼相同,如:10    補碼為 0000 1010
  • 負數(shù)的補碼是原碼除符號位外的所有位取反即0變1,1變0,然后加1,也就是反碼加1。

例如,-10的補碼如下:

原碼:1000 1010
反碼:1111 0101
補碼:1111 0110

1. 按位與操作符(&)

按位與操作符(&)會對參加運算的兩個數(shù)據(jù)按二進制位進行與運算,即兩位同時為 1 時,結(jié)果才為1,否則結(jié)果為0。運算規(guī)則如下:

0 & 0 = 0  
0 & 1 = 0  
1 & 0 = 0  
1 & 1 = 1

例如,3 & 5 的運算結(jié)果如下:

0000 0011 
   0000 0101 
 = 0000 0001

因此 3 & 5 的值為 1。需要注意:負數(shù)按補碼形式參加按位與運算。

用途:

(1)判斷奇偶

只要根據(jù)最未位是0還是1來決定,為0就是偶數(shù),為1就是奇數(shù)。因此可以用if ((i & 1) === 0)代替if (i % 2 === 0)來判斷a是不是偶數(shù)。

(2)清零

如果想將一個單元清零,即使其全部二進制位為0,只要與一個各位都為零的數(shù)值相與,結(jié)果為零。

2. 按位或操作符(|)

按位或操作符(|)會對參加運算的兩個對象按二進制位進行或運算,即參加運算的兩個對象只要有一個為1,其值為1。運算規(guī)則如下:

0 | 0 = 0
0 | 1 = 1  
1 | 0 = 1  
1 | 1 = 1

例如,3 | 5 的運算結(jié)果如下:

0000 0011
  0000 0101 
= 0000 0111

因此,3 | 5的值為7。需要注意:負數(shù)按補碼形式參加按位或運算。

3. 按位非操作符 (~)

按位非操作符 (~)會對參加運算的一個數(shù)據(jù)按二進制進行取反運算。即將0變成1,1變成0。運算規(guī)則如下:

~ 1 = 0
~ 0 = 1

例如:~6 的運算結(jié)果如下:

0000 0110
= 1111 1001

在計算機中,正數(shù)用原碼表示,負數(shù)使用補碼存儲,首先看最高位,最高位1表示負數(shù),0表示正數(shù)。此計算機二進制碼為負數(shù),最高位為符號位。

當(dāng)按位取反為負數(shù)時,就直接取其補碼,變?yōu)槭M制:

0000 0110
   = 1111 1001
反碼:1000 0110
補碼:1000 0111

因此,~6的值為-7。按位非的操作結(jié)果實際上是對數(shù)值進行取反并減1,

4. 按位異或運算符(^)

按位異或運算符(^)會對參加運算的兩個數(shù)據(jù)按二進制位進行“異或”運算,即如果兩個相應(yīng)位相同則為0,相異則為1。運算規(guī)則如下:

0 ^ 0 = 0  
0 ^ 1 = 1  
1 ^ 0 = 1  
1 ^ 1 = 0

例如, 3 ^ 5的運算結(jié)果如下:

0000 0011
  0000 0101 
= 0000 0110

因此,3^5的值為6。

異或運算具有以下性質(zhì):

  • 交換律:(a^b)^c == a^(b^c)
  • 結(jié)合律:(a + b)^c == a^b + b^c
  • 對于任何數(shù)x,都有 x^x=0,x^0=x
  • 自反性: a^b^b=a^0=a;

5. 左移操作符(<<)

左移操作符(<<)會將運算對象的各二進制位全部左移若干位,左邊的二進制位丟棄,右邊補0。若左移時舍棄的高位不包含1,則每左移一位,相當(dāng)于該數(shù)乘以2。

例如:

a = 1010 1110
a = a << 2

這里將a的二進制位左移2位、右補0,即得 a = 1011 1000。

需要注意,左移會保留他所操作數(shù)值的符號。比如,將-2左移5位,會得到-64,而不是64。

6. 右移運算符

(1)有符號右移操作符(>>)

有符號右移操作符(>>)會將數(shù)值的32位全部右移若干位(同時會保留正負號)。正數(shù)左補0,負數(shù)左補1,右邊丟棄。操作數(shù)每右移一位,相當(dāng)于該數(shù)除以2。

例如:a = a >>2 就是將a的二進制位右移2位,左補0 或者 左補1得看被移數(shù)是正還是負。

(2)無符號右移操作符(>>>)

無符號右移操作符(>>>)會將數(shù)值的32位全部右移。對于正數(shù),有符號右移操作符和無符號右移操作符的結(jié)果是一樣的。對于負數(shù)的操作,兩者就會有較大的差異。

無符號右移操作符將負數(shù)的二進制表示當(dāng)成正數(shù)的二進制表示來處理。所以,對負數(shù)進行無符號右移操作之后就會變的特別大。

三、加減乘除操作符

1. 加法操作符(+)

這里說的加法操作符就是二元的加操作符了。二元加操作符用于計算數(shù)值操作或者拼接字符串操作

1 + 1             // 2
"1" + "2"         // "12"
"hello" + "world" // "helloworld"

在進行加操作時,如果兩個操作數(shù)都是數(shù)值或者都是字符串,那么執(zhí)行結(jié)果就分別是計算出來的數(shù)值和拼接好的字符串。除此之外,執(zhí)行結(jié)果都取決于類型轉(zhuǎn)化的結(jié)果:它會優(yōu)先進行字符串拼接,只有操作數(shù)是字符串或者是可以轉(zhuǎn)化為字符串的對象,另一個操作數(shù)也會被轉(zhuǎn)化為字符串,并執(zhí)行拼接操作。只有任何操作數(shù)都不是字符串時才會執(zhí)行加法操作。

1 + 2             // 3
"1" + "2"         // "12"
"1" + 2           // "12"
1 + {}            // "1[object Object]"
true + false      // 1  布爾值會先轉(zhuǎn)為數(shù)字,再進行運算
1 + null          // 1 null會轉(zhuǎn)化為0,再進行計算
1 + undefined     // NaN undefined轉(zhuǎn)化為數(shù)字是NaN

需要注意加操作的順序:

let a = 1;
let b = 2;
let c = "hello" + a + b;  // "hello12"

這里,由于每次加法操作都是獨立完成的,第一次是字符串hello和數(shù)字a做加法操作,得到的結(jié)果是"hello1",第二次加法操作仍然是一個字符串加一個數(shù)字,所以最終結(jié)果是一個字符串。如果想讓a和b兩個數(shù)字相加,就需要加上括號。

除此之外,還需要注意以下特殊情況:

  • 如果有一個操作數(shù)是NaN,則結(jié)果是NaN;
  • 如果是Infinity加Infinity,則結(jié)果是Infinity;
  • 如果是-Infinity加-Infinity,則結(jié)果是-Infinity;
  • 如果是Infinity加-Infinity,則結(jié)果是NaN;
  • 如果是+0加+0,則結(jié)果是+0;
  • 如果是-0加-0,則結(jié)果是-0;
  • 如果是+0加-0,則結(jié)果是+0。

2. 減法操作符(-)

減法操作和加法操作符類似, 但是減法操作符只能用于數(shù)值的計算,不能用于字符串的拼接。當(dāng)進行減法操作時,如果兩個操作數(shù)都是數(shù)值,就會直接進行減法操作,如果有一個操作數(shù)是非數(shù)值,就會將其轉(zhuǎn)化為數(shù)值,再進行減法操作。如果轉(zhuǎn)化結(jié)果為NaN,則運算結(jié)果也是NaN。

3 - 1      // 2
3 - true   // 2
3 - ""     // 3
3 - null   // 3
NaN - 1    // NaN

需要注意以下特殊情況:

  1. 如果是Infinity減Infinity,則結(jié)果是NaN;
  2. 如果是-Infinity減-Infinity,則結(jié)果是NaN;
  3. 如果是Infinity減-Infinity,則結(jié)果是Infinity;
  4. 如果是-Infinity減Infinity,則結(jié)果是-Infinity;
  5. 如果是+0減+0,則結(jié)果是+0;
  6. 如果是-0減+0,則結(jié)果是-0;
  7. 如果是-0減-0,則結(jié)果是+0。

3. 乘法操作符(*)

乘法操作符用于計算兩個數(shù)的乘積。如果兩個操作數(shù)都是數(shù)值,則會執(zhí)行常規(guī)的乘法運算。如果不是數(shù)值,會將其轉(zhuǎn)化為數(shù)值,在進行乘法操作。

需要注意以下特殊情況:

  • 如果有一個操作數(shù)是NaN,則結(jié)果是NaN;
  • 如果Infinity與0相乘,則結(jié)果是NaN;
  • 如果Infinity與非0數(shù)值相乘,則結(jié)果是Infinity或-Infinity,取決于有符號操作數(shù)的符號;
  • 如果Infinity與Infinity相乘,則結(jié)果是Infinity。

4. 除法操作符(/)

除法操作符用于計算一個操作數(shù)除以第二個操作數(shù)的商。如果兩個操作數(shù)都是數(shù)值,則會執(zhí)行常規(guī)的除法運算。如果不是數(shù)值,會將其轉(zhuǎn)化為數(shù)值,在進行除法操作。

需要注意以下特殊情況:

  • 如果有一個操作數(shù)是NaN,則結(jié)果是NaN;
  • 如果0除以0,則結(jié)果是NaN;
  • 如果Infinity除以Infinity,則結(jié)果是Infinity。
  • 如果是非零的有限數(shù)被零除,則結(jié)果是Infinity或-Infinity,取決于有符號操作數(shù)的符號;
  • 如果是Infinity被任何非零數(shù)值除,則結(jié)果是Infinity或-Infinity,取決于有符號操作數(shù)的符號。

5. 取余操作符(%)

取余操作符用于計算一個數(shù)除以第二個數(shù)的余數(shù)。計算規(guī)則和上述運算符類似。

需要注意以下特殊情況:

  • 如果被除數(shù)是無窮大值而除數(shù)是有限大的數(shù)值,則結(jié)果是NaN;
  • 如果被除數(shù)是有限大的數(shù)值而除數(shù)是零,則結(jié)果是NaN;
  • 如果是Infinity被Infinity除,則結(jié)果是NaN;
  • 如果被除數(shù)是有限大的數(shù)值而除數(shù)是無窮大的數(shù)值,則結(jié)果是被除數(shù);
  • 如果被除數(shù)是零,則結(jié)果是零。

6. 指數(shù)操作符(**)

在ECMAScript 7中新增了指數(shù)操作符(**),它的計算效果是Math.pow()是一樣的:

Math.pow(2, 10);    // 1024
2 ** 10;            // 1024

指數(shù)運算符和上面的加減乘除運算符都有對應(yīng)的賦值操作運算符:

let a = 2;
a **= 10;
console.log(a);   // 1024
let a = 1;
let b = 2;
let c = 3;
let d = 4;
a += 1;     // 2
b -= 2;     // 0
c *= 3;     // 9
d /= 4;     // 1

四、布爾操作符

在開發(fā)時,布爾操作符是很有用的,可以精簡很多代碼,干掉很多多余的id-else語句,下面來看看常見的三種布爾操作符。

1. 邏輯非操作符(!)

邏輯非操作符可以用于JavaScript中的任何值,這個操作符使用返回布爾值。邏輯非操作符首先會將操作數(shù)轉(zhuǎn)化為布爾值,然后在對其取反。

邏輯非操作規(guī)則如下:

  • 如果操作數(shù)是對象,則返回 false;
  • 如果操作數(shù)是空字符串,則返回 true;
  • 如果操作數(shù)是非空字符串,則返回 false;
  • 如果操作數(shù)是數(shù)值0,則返回 true;
  • 如果操作數(shù)是非0數(shù)值(包括 Infinity),則返回 false;
  • 如果操作數(shù)是 null,則返回 true;
  • 如果操作數(shù)是 NaN,則返回 true;
  • 如果操作數(shù)是 undefined, 則返回 true.

邏輯非操作符也可以用于將任何值轉(zhuǎn)化為布爾值,同時使用兩個!,相當(dāng)于調(diào)用了Boolean()方法:

!!"blue" // true
!!0;     // false
!!NaN    // false
!!""     // false
!!12345  // true

2. 邏輯與操作符(&&)

邏輯與操作符的兩個操作數(shù)都為真時,最終結(jié)果才會返回真。該運算符可以用于任何類型的數(shù)據(jù)。如果有操作數(shù)不是布爾值,則結(jié)果并一定會返回布爾值,會遵循以下規(guī)則:

  • 如果第一個操作數(shù)是對象,則返回第二個操作數(shù);
  • 如果第二個操作數(shù)是對象,則只有在第一個操作數(shù)的求值結(jié)果為true的情況下才會返回該對象;
  • 如果兩個操作數(shù)都是對象,則返回第二個操作數(shù);
  • 如果第一個操作數(shù)是null,則返回null;
  • 如果第一個操作數(shù)是NaN,則返回NaN;
  • 如果第一個操作數(shù)是undefined,則返回undefined;

根據(jù)第二條規(guī)則,我們可以對我們項目代碼中的代碼進行優(yōu)化:

if(data) {
  setData(data);
}

// 改寫后:
data && setData(data);

這里當(dāng)data為真時,也就是存在時,才會執(zhí)行setData方法,代碼就精簡了很多。

邏輯與操作符是一種短路操作符,只要第一個操作數(shù)為false,就不會繼續(xù)執(zhí)行運算符后面的表達式,直接返回false。上面的data如果是不存在的,就會直接發(fā)生短路,不會繼續(xù)執(zhí)行后面的方法。

3. 邏輯或操作符(||)

邏輯或操作符和邏輯與操作符類似,不過只要兩個操作數(shù)中的一個為真,最終的結(jié)果就為真。該運算符可以用于任何類型的數(shù)據(jù)。如果有操作數(shù)不是布爾值,則結(jié)果并一定會返回布爾值,會遵循以下規(guī)則:

  • 如果第一個操作數(shù)是對象,則返回第一個操作對象;
  • 如果第一個操作數(shù)的求值結(jié)果是false,則返回第二個操作數(shù);
  • 如果兩個操作數(shù)都是對象,則返回第一個操作數(shù);
  • 如果兩個操作數(shù)都是null,則返回null;
  • 如果兩個數(shù)都是NaN,則返回NaN;
  • 如果兩個數(shù)都是undefined,則返回undefined。

邏輯或操作符也是具有短路特性,如果第一個操作數(shù)為真,那么第二個操作數(shù)就不需要在進行判斷了,會直接返回true。

可以利用這個特性給變量設(shè)置默認值:

let datas = data || {};

這里,如果data不存在,就會將datas賦值為第二個操作數(shù)(默認值)。

五、比較操作符

1. 相等操作符

相等操作符包括四種:

  • 等于(==)
  • 不等于(!=)
  • 全等(===)
  • 不全等(!==)

JavaScript中的等于用兩個等號(==)表示,如果兩個操作數(shù)相等,那么就返回true。不等于和等于相反。在進行比較時,兩個操作數(shù)都會進行強制類型轉(zhuǎn)換,在確實是否相等。其判斷規(guī)則如下:

  • 首先會判斷兩者類型是否相同,相同的話就比較兩者的大小。
  • 類型不相同的話,就會進行類型轉(zhuǎn)換。
  • 會先判斷是否在對比 null 和 undefined,是的話就會返回 true。
  • 判斷兩者類型是否為 string 和 number,是的話就會將字符串轉(zhuǎn)換為 number。
1 == '1'
      ↓
1 ==  1
  • 判斷其中一方是否為 boolean,是的話就會把 boolean 轉(zhuǎn)為 number 再進行判斷。
'1' == true
        ↓
'1' ==  1
        ↓
 1  ==  1
  • 判斷其中一方是否為 object 且另一方為 string、number 或者 symbol,是的話就會把 object 轉(zhuǎn)為原始類型再進行判斷。
'1' == { name: 'js' }        
 ↓
'1' == '[object Object]'

其流程圖如下:

需要注意,如果其中一個操作數(shù)是NaN,相等運算符會返回false,不相等運算符會返回true。

對于不等于運算符(!=),只有在強制類型轉(zhuǎn)化后不相等才會返回true。

對于全等運算符(===),只有當(dāng)兩個操作數(shù)的數(shù)據(jù)類型和值都相等時,才會返回true。它并不會進行數(shù)據(jù)類型的轉(zhuǎn)化。

對于不全等運算符(!==),只有兩個操作數(shù)在不進行類型轉(zhuǎn)化的情況下是不相等的,才會返回true。

在平時的開發(fā)中,建議使用全等和不全等在做比較,這樣會更加嚴謹,避免出現(xiàn)意料之外的結(jié)果。

2. 關(guān)系操作符

關(guān)系操作符包括四種:

  • 小于(<)
  • 大于(>)
  • 小于等于(<=)
  • 大于等于(>=)

這幾個操作符都會返回一個布爾值,他們操作時會遵循以下規(guī)則:

  • 如果這兩個操作數(shù)都是數(shù)值,則執(zhí)行數(shù)值比較;
  • 如果兩個操作數(shù)都是字符串,則比較兩個字符串對應(yīng)的字符編碼值;
  • 如果一個操作數(shù)是數(shù)值,則將另一個操作數(shù)轉(zhuǎn)換為一個數(shù)值,然后執(zhí)行數(shù)值比較;
  • 如果一個操作數(shù)是對象,則調(diào)用這個對象的valueOf()方法,并用得到的結(jié)果根據(jù)前面的規(guī)則執(zhí)行比較;
  • 如果一個操作數(shù)是布爾值,則先將其轉(zhuǎn)換為數(shù)值,然后再執(zhí)行比較。

六、其他操作符

最后這一部分的一些操作符在平時的開發(fā)中就很實用了,下面來看看它們的用法吧。

1. 擴展運算符(...)

擴展操作符(Spread operator)可以用來擴展一個數(shù)組對象和字符串。它用三個點(…)表示,可以將可迭代對象轉(zhuǎn)為用逗號分隔的參數(shù)序列。

(1)用于展開數(shù)組:

const a = [1, 2, 3],
      b = [4, 5, 6];
const c = [...a]       // [1, 2, 3]
const d = [...a, ...b] // [1, 2, 3, 4, 5, 6]
const e = [...a, 4, 5] // [1, 2, 3, 4, 5]

(2)將類數(shù)組對象變成數(shù)組:

const list = document.getElementsByTagName('a');
const arr = [..list];

(3)用于展開對象:

const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 };  // { a: 1, b: 2, c: 3, d: 4 }

需要注意,如果合并時的多個對象有相同屬性,則后面的對象的會覆蓋前面對象的屬性。

(4)用于展開字符串

const str = "hello";
[...str]  // ["h", "e", "l", "l", "o"]

(5)用于函數(shù)傳參

const f = (foo, bar) => {}
const a = [1, 2]
f(...a)

const numbers = [1, 2, 3, 4, 5]
const sum = (a, b, c, d, e) => a + b + c + d + e
const sum = sum(...numbers)

(6)用于具有 Iterator 接口的對象

具有 Iterator 接口的對象 Map 和 Set 結(jié)構(gòu),Generator 函數(shù),可以使用展開操作符:

const s = new Set();
s.add(1);
s.add(2);
const arr = [...s]// [1,2]


function * gen() {
  yield 1;
  yield 2;
  yield 3;
}

const arr = [...gen()] // 1,2,3

如果是map,會把每個key 和 value 轉(zhuǎn)成一個數(shù)組:

const m = new Map();
m.set(1,1)
m.set(2,2)
const arr = [...m]  // [[1,1],[2,2]]

注意 ,對象不是一個Iterator對象。

2. 條件操作符(?:)

這里的條件運算符實際上就是我們常說的三元表達式??匆粋€例子:

let res = num1 > num2 ? num1 : num2;

這里,將num1和num2中的最大值賦值給了res。

使用條件表達式可以代替很多if-else,使得代碼很簡潔。在React的項目中,我個人就經(jīng)常使用條件操作符來做組件的條件渲染。當(dāng)然如果判斷的層數(shù)過多,感覺代碼就有些難讀懂了。(React-Router源碼中就有嵌套了六七層條件操作符的地方,很難理解...)

3. 賦值操作符

其實賦值操作符有很多種,包括簡單的賦值操作符(=),以及一些復(fù)合賦值操作符:

  • 乘賦值操作符:*=
  • 除賦值操作符:/=
  • 模賦值操作符:%=
  • 加賦值操作符:+=
  • 減賦值操作符:-=
  • 左移操作符: <<=
  • 有符號右移賦值操作符:>>=
  • 無符號右移賦值操作符:>>>=

這些僅僅是他們對應(yīng)的簡寫形式,并不會產(chǎn)生其他影響。

4. in操作符

in操作符可以用來判斷一個屬性是否屬于一個對象,它的返回值是一個布爾值:

const author = {
  name: "CUGGZ",
  age: 18
}

"height" in author;  // false
"age" in author;     // true

還可以用來判斷一個屬性是否屬于對象原型鏈的一部分:

let arr = ["hello", "jue", "jin"];
"length" in arr;   // true

5. delete操作符

delete 操作符用于刪除對象的某個屬性或者數(shù)組元素。對于引用類型的值,它也是刪除對象屬性的本身,不會刪除屬性指向的對象。

const o = {};
const a = { x: 10 };
o.a = a;
delete o.a; // o.a屬性被刪除
console.log(o.a); // undefined
console.log(a.x); // 10, 因為{ x: 10 } 對象依然被 a 引用,所以不會被回收

需要注意:

  • 原型中聲明的屬性和對象自帶的屬性無法被刪除;
  • 通過var聲明的變量和通過function聲明的函數(shù)擁有dontdelete特性,是不能被刪除。

6. instanceof操作符

instanceof運算符用來判斷一個構(gòu)造函數(shù)的prototype屬性所指向的對象是否存在另外一個要檢測對象的原型鏈上。

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

可以看到,instanceof只能正確判斷引用數(shù)據(jù)類型,而不能判斷基本數(shù)據(jù)類型。instanceof運算符可以用來測試一個對象在其原型鏈中是否存在一個構(gòu)造函數(shù)的 prototype 屬性。

可以簡單來實現(xiàn)一下 instanceof 操作符:

function myInstanceof(left, right) {
  // 獲取對象的原型
  let proto = Object.getPrototypeOf(left)
  // 獲取構(gòu)造函數(shù)的 prototype 對象
  let prototype = right.prototype; 
 
  // 判斷構(gòu)造函數(shù)的 prototype 對象是否在對象的原型鏈上
  while (true) {
    if (!proto) return false;
    if (proto === prototype) return true;
    // 如果沒有找到,就繼續(xù)從其原型上找,Object.getPrototypeOf方法用來獲取指定對象的原型
    proto = Object.getPrototypeOf(proto);
  }
}

7. typeof操作符

typeof是一元運算符,它的返回值是一個字符串,它是操作數(shù)的類型,JavaScript常見數(shù)據(jù)對應(yīng)的類型如下:

x

typeof

undefined

undefined

null

object

true或false

boolean

數(shù)值或NaN

number

BigInt

bigInt

字符串

string

symbol

symbol

函數(shù)

function

非函數(shù)對象

object

typeof 2               // number
typeof true            // boolean
typeof 'str'           // string
typeof []              // object    
typeof function(){}    // function
typeof {}              // object
typeof undefined       // undefined
typeof null            // object

那這里為什么 typeof null 的結(jié)果是Object呢?

在 JavaScript 第一個版本中,所有值都存儲在 32 位的單元中,每個單元包含一個小的 類型標(biāo)簽(1-3 bits) 以及當(dāng)前要存儲值的真實數(shù)據(jù)。類型標(biāo)簽存儲在每個單元的低位中,共有五種數(shù)據(jù)類型:

000: object   - 當(dāng)前存儲的數(shù)據(jù)指向一個對象。
  1: int      - 當(dāng)前存儲的數(shù)據(jù)是一個 31 位的有符號整數(shù)。
010: double   - 當(dāng)前存儲的數(shù)據(jù)指向一個雙精度的浮點數(shù)。
100: string   - 當(dāng)前存儲的數(shù)據(jù)指向一個字符串。
110: boolean  - 當(dāng)前存儲的數(shù)據(jù)是布爾值。

如果最低位是 1,則類型標(biāo)簽標(biāo)志位的長度只有一位;如果最低位是 0,則類型標(biāo)簽標(biāo)志位的長度占三位,為存儲其他四種數(shù)據(jù)類型提供了額外兩個 bit 的長度。

有兩種特殊數(shù)據(jù)類型:

  • undefined的值是 (-2)30(一個超出整數(shù)范圍的數(shù)字)。
  • null 的值是機器碼 NULL 指針(null 指針的值全是 0)。

那也就是說null的類型標(biāo)簽也是000,和Object的類型標(biāo)簽一樣,所以會被判定為Object。

8. 空值合并操作符(??)

在編寫代碼時,如果某個屬性不為 null 和 undefined,那么就獲取該屬性,如果該屬性為 null 或 undefined,則取一個默認值:

const name = dogName ? dogName : 'default';

可以通過 || 來簡化:

const name =  dogName || 'default';

但是 || 的寫法存在一定的缺陷,當(dāng) dogName 為 0 或 false 的時候也會走到 default 的邏輯。所以 ES2020 引入了 ?? 運算符。只有 ?? 左邊為 null 或 undefined時才返回右邊的值:

const dogName = false; 
const name =  dogName ?? 'default';  // name = false;

9. 可選鏈操作符(?.)

在開發(fā)過程中,我們可能需要獲取深層次屬性,例如 system.user.addr.province.name。但在獲取 name 這個屬性前需要一步步的判斷前面的屬性是否存在,否則并會報錯:

const name = (system && system.user && system.user.addr && system.user.addr.province && system.user.addr.province.name) || 'default';

為了簡化上述過程,ES2020 引入了「鏈判斷運算符」?.,可選鏈操作符( ?. )允許讀取位于連接對象鏈深處的屬性的值,而不必明確驗證鏈中的每個引用是否有效。?. 操作符的功能類似于 . 鏈?zhǔn)讲僮鞣?,不同之處在于,在引用為null 或 undefined 的情況下不會引起錯誤,該表達式短路返回值是 undefined。與函數(shù)調(diào)用一起使用時,如果給定的函數(shù)不存在,則返回 undefined。

const name = system?.user?.addr?.province?.name || 'default';

當(dāng)嘗試訪問可能不存在的對象屬性時,可選鏈操作符將會使表達式更短、更簡明。在探索一個對象的內(nèi)容時,如果不能確定哪些屬性必定存在,可選鏈操作符也是很有幫助的。

可選鏈有以下三種形式:

a?.[x]
// 等同于
a == null ? undefined : a[x]

a?.b()
// 等同于
a == null ? undefined : a.b()

a?.()
// 等同于
a == null ? undefined : a()

10. 逗號操作符(,)

逗號操作符也沒啥好說的,當(dāng)同時聲明多個變量時會用到:

let a = 1, b = 2, c = 3;

還有一種使用場景就是有多個循環(huán)變量的 for 循環(huán)中:

for(let i = 0, j = 10; i < j; i++, j--){
  console.log(i + j);
}

11. void操作符(void)

void 是一元運算符,它可以出現(xiàn)在任意類型的操作數(shù)之前執(zhí)行操作數(shù),會忽略操作數(shù)的返回值,返回一個 undefined。void 常用于 HTML 腳本中執(zhí)行 JavaScript 表達式,但不需要返回表達式的計算結(jié)果。比如對于鏈接標(biāo)簽,我們并不想讓它發(fā)生跳轉(zhuǎn),就可以設(shè)置href="javascript:void(0)。

在下面代碼中,使用 void 運算符讓表達式返回 undefined:

let a = b = c = 2;  // 定義并初始化變量的值
d = void (a -= (b *= (c += 5)));  // 執(zhí)行void運算符,并把返回值賦予變量d
console.log(a);  // -12
console.log(b);  // 14
console.log(c);  // 7
console.log(d);  // undefined

由于 void 運算符的優(yōu)先級比較高,高于普通運算符的優(yōu)先級,所以在使用時應(yīng)該使用小括號明確 void 運算符操作的操作數(shù),避免引發(fā)錯誤。

責(zé)任編輯:姜華 來源: 前端充電寶
相關(guān)推薦

2022-09-07 09:01:14

JS操作符運算符

2021-08-05 18:21:29

Autowired代碼spring

2022-11-10 09:00:41

2020-05-27 11:30:54

Chrome DevT前端命令

2016-01-11 09:48:07

2016-03-18 19:03:35

認知計算IBM

2019-07-08 10:18:38

MPLSIP數(shù)據(jù)

2019-02-12 11:15:15

Spring設(shè)計模式Java

2021-07-29 06:55:03

Spring@AutowriedbyType注入

2021-01-20 15:20:02

JS操作符前端

2024-04-28 08:20:52

Controller接口URL

2023-02-15 08:12:19

http超時過濾器

2020-10-28 11:20:55

vue項目技

2021-04-10 07:04:00

WPS技巧辦公軟件

2023-08-29 09:31:01

Scrapy網(wǎng)頁爬蟲

2020-02-20 08:30:49

OSPF網(wǎng)絡(luò)協(xié)議路由協(xié)議

2018-02-06 09:06:03

主流分布式存儲系統(tǒng)

2024-04-09 11:40:58

DartJSWasmGC

2025-01-28 00:00:00

OpenFeign接口依賴

2015-06-29 09:06:51

點贊
收藏

51CTO技術(shù)棧公眾號

成人在线资源网址| www.久久久久| www.亚洲天堂网| 免费在线稳定资源站| 欧美特黄aaaaaaaa大片| 久久综合九色综合97_久久久| 国产91色在线|| 日本二区三区视频| 97品白浆高清久久久久久| 91网站在线播放| 国产精品免费久久久久久| 九九精品视频免费| 麻豆精品99| 亚洲人成影院在线观看| 国产二区一区| 成人黄色激情视频| 国产精品xvideos88| 亚洲人免费视频| 熟妇无码乱子成人精品| 欧美一级大片| 夜夜精品视频一区二区| 日本一区二区三区视频在线观看 | 精品久久久久久中文字幕大豆网| 国产女精品视频网站免费| 国产性一乱一性一伧一色| 精品精品久久| 亚洲国产97在线精品一区| 亚洲77777| 亚洲插插视频| 亚洲高清在线视频| 91香蕉视频网址| 六十路在线观看| 成人综合在线网站| 91欧美精品午夜性色福利在线| 国产精品老女人| 欧美韩国一区| 久久偷看各类女兵18女厕嘘嘘| 在线 丝袜 欧美 日韩 制服| 亚洲亚洲一区二区三区| 在线不卡的av| 精品久久久久久久久久中文字幕| 亚洲美女综合网| 久久国产剧场电影| 国产精品69av| 日本韩国欧美中文字幕| 欧美午夜久久| 久久在线免费观看视频| 制服丨自拍丨欧美丨动漫丨| 国产一区99| 欧美视频中文一区二区三区在线观看| 国产69精品久久久久999小说| www.久久久久.com| 亚洲欧洲成人自拍| 一区二区三区四区五区精品| 国产天堂在线| 日本一区二区三区视频视频| 日本不卡一二三区| 伦理片一区二区三区| 91丝袜国产在线播放| 国产在线视频欧美一区二区三区| 亚洲av无码专区在线| 国产精品12区| 97色在线视频| 国产精品99无码一区二区| 欧亚精品一区| 欧美日韩1234| 超碰在线免费av| 成人污污www网站免费丝瓜| 欧美浪妇xxxx高跟鞋交| 日本高清久久久| xxxx成人| 精品免费在线观看| wwwxxx黄色片| 91大神在线观看线路一区| 欧美三级欧美一级| 久久综合在线观看| 最新精品在线| 日韩成人av在线| 91成年人网站| 91成人在线精品视频| 精品国产一区二区三区av性色| 佐佐木明希电影| 清纯唯美亚洲经典中文字幕| 精品亚洲国产视频| 丁香六月激情综合| 欧美va亚洲va日韩∨a综合色| 欧美激情女人20p| 中文字幕激情小说| 美女国产一区二区| 91一区二区三区| 视频一区二区三区在线看免费看| 国产无遮挡一区二区三区毛片日本| 亚洲欧美日韩国产yyy| 中国av在线播放| 欧美午夜宅男影院在线观看| 成人小视频在线观看免费| 成入视频在线观看| 欧美在线免费观看亚洲| 亚欧美一区二区三区| 少妇精品导航| 久久久黄色av| 久久久免费高清视频| 久久97超碰色| 久久久综合亚洲91久久98| 蜜桃视频在线观看www社区 | 伊人色综合久久天天五月婷| 七七久久电影网| 在线观看欧美黄色| 第一页在线视频| 日韩成人综合| 69av视频在线播放| 国产999久久久| 国产午夜亚洲精品不卡| 亚洲精品久久久久久久蜜桃臀| 欧美性xxx| 欧美精品一区二区三区很污很色的 | 精品一级少妇久久久久久久| 日韩电影在线观看电影| 国产精品久久波多野结衣| 98在线视频| 欧美日韩另类字幕中文| 精品人妻一区二区三区免费| 精品99在线| 91国产精品电影| 99视频在线观看免费| 中文字幕免费在线观看视频一区| 缅甸午夜性猛交xxxx| 日韩三级网址| www.日韩系列| 91黑人精品一区二区三区| 在线亚洲激情| 国产91成人video| 日本少妇激情视频| 国产精品一区二区久久不卡| 性刺激综合网| 国产精品高清乱码在线观看| 亚洲激情小视频| 久久老司机精品视频| 国产一区久久久| 亚洲精品人成| 99欧美精品| 尤物yw午夜国产精品视频| 俄罗斯毛片基地| 久久裸体视频| 欧美日本韩国在线| 手机在线观看av网站| 亚洲国产成人精品电影| 久久精品视频日本| 成人一区二区三区视频在线观看| 国产手机视频在线观看| 国产一区二区高清在线| 久久中文久久字幕| 国产美女三级无套内谢| 亚洲美女视频在线观看| 日韩av加勒比| 欧美日韩亚洲一区三区| 国产91亚洲精品一区二区三区| av在线app| 日韩免费看网站| 精品一级少妇久久久久久久| 成人av电影在线观看| 99热亚洲精品| 伊人久久大香线蕉无限次| 国产91精品网站| 国产对白叫床清晰在线播放| 精品污污网站免费看| 激情无码人妻又粗又大| 国产精品影视天天线| 国产黄色激情视频| 欧美综合自拍| 国产精品久久久久久久久久久久久| 成人在线免费观看| 91精品国产一区二区三区蜜臀| 国产黄色的视频| 成+人+亚洲+综合天堂| 男人天堂999| 欧美欧美在线| 久久久久久网站| 天堂а√在线8种子蜜桃视频| 精品久久久中文| 一级黄色毛毛片| 国产精品一区二区久久精品爱涩| aa视频在线播放| 国产精品一区二区av日韩在线| 国产精品视频免费在线| 亚洲图区一区| 亚洲欧美日韩天堂一区二区| 国产精品久久久久久久一区二区 | 国产又大又黑又粗免费视频| 91麻豆免费看片| 亚洲xxx在线观看| 在线成人亚洲| 亚洲综合大片69999| 秋霞伦理一区| 色狠狠av一区二区三区香蕉蜜桃| 国内精品偷拍视频| 色综合激情久久| 日韩黄色免费观看| 久久久久久久av麻豆果冻| 欧美一级小视频| 国产精品一二| 亚洲色图都市激情| 久草成人在线| 国产高清在线精品一区二区三区| 日韩网站中文字幕| 久久免费福利视频| 都市激情一区| 亚洲电影免费观看高清完整版在线观看 | 欧美视频国产视频| 亚洲欧美bt| 蜜桃视频一区二区在线观看| 国产日韩欧美一区二区三区| eeuss一区二区三区| av毛片在线看| 亚洲欧洲中文天堂| 国模私拍视频在线| 欧美老人xxxx18| 五月婷婷六月婷婷| 亚洲成av人片一区二区| 国产老头老太做爰视频| 国产午夜三级一区二区三| 屁屁影院国产第一页| 亚洲美女啪啪| 一区二区三区四区久久| 欧美亚洲激情| 91精品久久久久久久久久 | 欧美日韩在线网站| 久久99精品国产99久久| 136导航精品福利| 国产自产女人91一区在线观看| 三上悠亚国产精品一区二区三区| 久久全球大尺度高清视频| 中文av资源在线| 久久激情视频免费观看| 香蕉视频在线免费看| 欧美精品免费视频| 男人天堂视频网| 欧美日韩在线免费| 好吊操这里只有精品| 亚洲综合色成人| 欧美日韩免费做爰视频| 亚洲人123区| www.xxxx日本| 亚洲人一二三区| 丝袜美腿小色网| √…a在线天堂一区| 黄色片网站在线播放| 中文幕一区二区三区久久蜜桃| 美女被到爽高潮视频| 久久一日本道色综合| 91中文字幕永久在线| 久久日韩粉嫩一区二区三区 | 中文字幕av一区二区三区高| 欧美大波大乳巨大乳| 亚洲国产高清在线观看视频| 国产又粗又猛又爽又黄的视频四季| 久久精品视频在线免费观看| 性色av蜜臀av色欲av| 久久女同互慰一区二区三区| 超碰97人人干| 国产色91在线| 女人18毛片毛片毛片毛片区二| 国产精品国模大尺度视频| www.xxxx日本| 亚洲不卡在线观看| 国产寡妇亲子伦一区二区三区四区| 欧美天天综合色影久久精品| 无码人妻久久一区二区三区不卡| 亚洲欧美怡红院| 国产高潮流白浆| 亚洲国产sm捆绑调教视频| 欧美三日本三级少妇99| 日本乱人伦aⅴ精品| 中文字幕乱码中文字幕| 日韩欧美一区在线观看| 天天操天天干天天舔| 亚洲夜晚福利在线观看| 东京干手机福利视频| 日韩精品欧美国产精品忘忧草| 韩国福利在线| 亚洲国产毛片完整版| 亚洲欧美综合一区二区| 永久免费看mv网站入口亚洲| 国产人成网在线播放va免费| 欧美激情va永久在线播放| 中文字幕高清在线播放| 91精品国产综合久久香蕉922| 亚洲专区**| 日韩亚洲欧美精品| 国产精品v亚洲精品v日韩精品| 777久久久精品一区二区三区| 免费成人美女在线观看| 色悠悠在线视频| 中文字幕高清不卡| 日产精品久久久久久久| 欧美午夜精品一区二区三区| 丰满少妇被猛烈进入| 国产亚洲美女精品久久久| 欧美男男video| 国产精品久久激情| 成人av综合网| 在线丝袜欧美日韩制服| 在线综合视频| 国产探花一区二区三区| 国产婷婷色一区二区三区| 欧美日韩在线观看成人| 欧美综合天天夜夜久久| 神马午夜一区二区| 久久视频免费在线播放| 黑人巨大精品欧美一区二区桃花岛| 91网站在线看| 不卡在线一区二区| 日韩av一二三四区| 国产精品18久久久久久久久久久久 | 亚洲人体在线| 日本免费一区二区三区| 精品动漫3d一区二区三区免费版| 亚洲欧美自拍另类日韩| 99国产精品99久久久久久| 成人观看免费视频| 欧美日韩高清一区二区不卡| 国内三级在线观看| 7777免费精品视频| 亚洲国产中文在线| 色香蕉在线观看| 丝瓜av网站精品一区二区| 国产chinese中国hdxxxx| 亚洲美女屁股眼交3| 91黄色在线视频| 国产一区二区激情| 欧美黑人粗大| 久久精品综合一区| 99亚洲伊人久久精品影院红桃| 精品人妻一区二区三| 亚洲欧洲精品天堂一级 | 日韩欧美电影一二三| 久久日韩视频| 国产日韩在线一区| 日韩极品一区| 校园春色 亚洲色图| 国产日韩三级在线| 男操女视频网站| 亚洲精品中文字幕av| jk漫画禁漫成人入口| 久久精品国产一区二区三区日韩 | 成人免费毛片网| av一区二区三区| 99久在线精品99re8热| 亚洲国产日韩欧美在线99| 国产极品人妖在线观看| 国产精品久久7| 国产一级久久| 蜜桃精品一区二区| 欧美影院精品一区| 天堂中文8资源在线8| 成人写真福利网| 欧美日韩一区二区国产| japan高清日本乱xxxxx| 亚洲一区免费在线观看| 人妻精品无码一区二区| 4k岛国日韩精品**专区| 久久不见久久见中文字幕免费| 99久久国产宗和精品1上映| 欧美激情综合在线| 国产一区二区在线视频聊天| 免费av在线一区| 国产精品极品在线观看| 凹凸国产熟女精品视频| 中文字幕精品在线不卡| 国产精品无码久久久久成人app| 欧美成aaa人片免费看| 国产精品极品| 五月婷婷深爱五月| 亚洲免费观看高清在线观看| 日本加勒比一区| 国产精国产精品| 国产精品久久久久久麻豆一区软件| 欧美视频在线第一页| 不卡一区二区中文字幕| 九九九在线观看| 日韩中文字幕国产| 国产精品调教| 四季av一区二区| 亚洲同性gay激情无套| 人妻少妇一区二区三区| 国产精品高潮在线| 欧美日韩国产欧| 中文字幕一区二区三区人妻电影| 欧美日韩一区二区三区四区| 污的网站在线观看| 欧美久久电影| 国产精品主播直播| 青青青国产在线| 久久久国产91| 免费视频亚洲| 久久出品必属精品| 色婷婷av一区二区三区gif| 手机在线免费看av| 日韩不卡av| av一区二区不卡|