成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

《JavaScript 闖關(guān)記》之表達(dá)式和運(yùn)算符

Render / 1020人閱讀

摘要:函數(shù)定義表達(dá)式。對象創(chuàng)建表達(dá)式。也就是說,空字符串將被當(dāng)作,布爾值將被當(dāng)作。如果有一個(gè)操作數(shù)是對象數(shù)值或布爾值,則調(diào)用它們的方法取得相應(yīng)的字符串值,然后再應(yīng)用前面關(guān)于字符串的規(guī)則。對于和,則分別調(diào)用函數(shù)并取得字符串和。

表達(dá)式

表達(dá)式是由數(shù)字、運(yùn)算符、數(shù)字分組符號(如括號)、自由變量和約束變量等以能求得數(shù)值的有意義排列方法所得的組合。JavaScript 表達(dá)式主要有以下幾種形式:

原始表達(dá)式:常量、變量、保留字。

對象、數(shù)組初始化表達(dá)式:var obj={a:1,b:2};,var arr=[1,2,3];。

函數(shù)定義表達(dá)式:var fn=function(){}

屬性訪問表達(dá)式:Math.abs。

調(diào)用表達(dá)式:alert("hello");

對象創(chuàng)建表達(dá)式:new object();。

運(yùn)算符

JavaScript 中的運(yùn)算符用于算術(shù)表達(dá)式、比較表達(dá)式、邏輯表達(dá)式、賦值表達(dá)式等。需要注意的是,大多數(shù)運(yùn)算符都是由標(biāo)點(diǎn)符號表示的,比如 +=。而另外一些運(yùn)算符則是由關(guān)鍵字表示的,比如 typeofinstanceof,關(guān)鍵字運(yùn)算符和標(biāo)點(diǎn)符號都是正規(guī)的運(yùn)算符。

下表列出了 JavaScript 中所有的運(yùn)算符,并按照運(yùn)算符的優(yōu)先級排序的,前面的運(yùn)算符優(yōu)先級要高于后面的運(yùn)算符優(yōu)先級,被空行分隔開來的運(yùn)算符具有不同的優(yōu)先級。標(biāo)題為 A 的列表示運(yùn)算符的結(jié)合性(Associativity),L 表示從左至右、R 表示從右至左,標(biāo)題為 N 的列表示操作數(shù)的個(gè)數(shù)(Number)。

運(yùn)算符 操作 A N
++ 前/后增量 R 1
-- 前/后增量 R 1
- 求反 R 1
+ 轉(zhuǎn)換為數(shù)字 R 1
~ 按位求反 R 1
! 邏輯非 R 1
delete 刪除屬性 R 1
typeof 檢測類型 R 1
void 返回undefined R 1
* / % 乘,除,求模 L 2
+ - 加,減 L 2
+ 字符串連接 L 2
<< 左移位 L 2
>> 有符號右移 L 2
>>> 無符號右移 L 2
< <= > >= 比較數(shù)字順序 L 2
< <= > >= 比較字母順序 L 2
instanceof 測試對象類 L 2
in 測試屬性是否存在 L 2
== 判斷相等 L 2
!= 判斷不等 L 2
=== 判斷恒等 L 2
!== 判斷恒不等 L 2
& 按位與 L 2
^ 按位異或 L 2
按位或 L 2
&& 邏輯與 L 2
┃┃ 邏輯或 L 2
?: 條件運(yùn)算符 R 3
= 賦值 R 2
*= /= %=
+= -= &=
<<= >>=
^= ┃= >>>=
運(yùn)算且賦值 R 2
, 忽略第一個(gè)操作數(shù),
返回第二個(gè)操作數(shù)
L 2

因?yàn)?| 是制表符,會導(dǎo)致格式混亂,所以表格中的 | 均以 代替。

一元運(yùn)算符 delete 運(yùn)算符

delete 運(yùn)算符用來刪除對象屬性或者數(shù)組元素,如果刪除成功或所刪除的目標(biāo)不存在,delete 將返回 true。然而,并不是所有的屬性都可刪除,一些內(nèi)置核心和客戶端屬性是不能刪除的,通過 var 語句聲明的變量不能刪除,通過 function 語句定義的函數(shù)也是不能刪除的。例如:

var o = { x: 1, y: 2};          // 定義一個(gè)對象
console.log(delete o.x);        // true,刪除一個(gè)屬性
console.log(delete o.x);        // true,什么都沒做,x 在已上一步被刪除
console.log("x" in o);          // false,這個(gè)屬性在對象中不再存在
console.log(delete o.toString); // true,什么也沒做,toString是繼承來的
console.log(delete 1);          // true,無意義

var a = [1,2,3];                // 定義一個(gè)數(shù)組
console.log(delete a[2]);       // true,刪除最后一個(gè)數(shù)組元素
console.log(2 in a);            // false,元素2在數(shù)組中不再存在
console.log(a.length);          // 3,數(shù)組長度并不會因 delete 而改變
console.log(a[2]);              // undefined,元素2所在的位置被空了出來
console.log(delete a);          // false,通過 var 語句聲明的變量不能刪除

function f(args){}              // 定義一個(gè)函數(shù)
console.log(delete f);          // false,通過 function 語句聲明的函數(shù)不能刪除
void 運(yùn)算符

void 運(yùn)算符可以應(yīng)用于任何表類型的表達(dá)式,表達(dá)式會被執(zhí)行,但計(jì)算結(jié)果會被忽略并返回 undefined。例如:

void 0;
void "you are useless?";
void false;
void [];
void /(useless)/ig;
void function(){ console.log("you are so useless?"); }
// always return undefined

擴(kuò)展閱讀「談?wù)?JavaScript 中的 void 運(yùn)算符」
https://segmentfault.com/a/11...

typeof 運(yùn)算符

請參見「變量和數(shù)據(jù)類型」-「數(shù)據(jù)類型」-「typeof 運(yùn)算符」。

++ -- 運(yùn)算符

++ -- 遞增遞減運(yùn)算符借鑒自 C 語言,它們分前置型和后置型,作用是改變一個(gè)變量的值。例如:

var a = 5;
console.log(a++);   // 5
console.log(++a);   // 7
console.log(a--);   // 7
console.log(--a);   // 5
+ - 運(yùn)算符

當(dāng) + - 作為一元運(yùn)算符時(shí),應(yīng)用于數(shù)值,表示數(shù)值的正負(fù)。應(yīng)用于非數(shù)值,先按 Number() 轉(zhuǎn)型函數(shù)對這個(gè)值執(zhí)行轉(zhuǎn)換,再表示該值的正負(fù)。

~ ! 運(yùn)算符

~ 按位非運(yùn)算符,請參見下面「位運(yùn)算符」。
! 邏輯非運(yùn)算符,請參見下面「邏輯運(yùn)算符」。

乘性運(yùn)算符

JavaScript 定義了3個(gè)乘性運(yùn)算符:乘法、除法和求模。這些運(yùn)算符與 C 語言的相應(yīng)運(yùn)算符用途類似,只不過在操作數(shù)為非數(shù)值的情況下會執(zhí)行自動的類型轉(zhuǎn)換。如果參與乘法計(jì)算的某個(gè)操作數(shù)不是數(shù)值,后臺會先使用 Number() 轉(zhuǎn)型函數(shù)將其轉(zhuǎn)換為數(shù)值。也就是說,空字符串將被當(dāng)作 0,布爾值 true 將被當(dāng)作 1。

* 乘法運(yùn)算符

用于計(jì)算兩個(gè)數(shù)值的乘積,在處理特殊值的情況下,乘法運(yùn)算符遵循下列特殊的規(guī)則:

如果操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的乘法計(jì)算,即兩個(gè)正數(shù)或兩個(gè)負(fù)數(shù)相乘的結(jié)果還是正數(shù),而如果只有一個(gè)操作數(shù)有符號,那么結(jié)果就是負(fù)數(shù)。如果乘積超過了 JavaScript 數(shù)值的表示范圍,則返回 Infinity-Infinity

如果有一個(gè)操作數(shù)是 NaN,則結(jié)果是 NaN

如果是 Infinity0 相乘,則結(jié)果是 NaN

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

如果是 InfinityInfinity 相乘,則結(jié)果是 Infinity;
如果有一個(gè)操作數(shù)不是數(shù)值,則在后臺調(diào)用 Number()將其轉(zhuǎn)換為數(shù)值,然后再應(yīng)用上面的規(guī)則。

/ 除法運(yùn)算符

用于計(jì)算兩個(gè)數(shù)值的商,與乘法運(yùn)算符類似,除法運(yùn)算符對特殊的值也有特殊的處理規(guī)則。這些規(guī)則如下:

如果操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的除法計(jì)算,即兩個(gè)正數(shù)或兩個(gè)負(fù)數(shù)相除的結(jié)果還是正數(shù),而如果只有一個(gè)操作數(shù)有符號,那么結(jié)果就是負(fù)數(shù)。如果商超過了 JavaScript 數(shù)值的表示范圍,則返回 Infinity-Infinity;

如果有一個(gè)操作數(shù)是 NaN,則結(jié)果是 NaN;

如果是 InfinityInfinity 除,則結(jié)果是 NaN;

如果是零被零除,則結(jié)果是 NaN

如果是非零的有限數(shù)被零除,則結(jié)果是 Infinity-Infinity,取決于有符號操作數(shù)的符號;

如果是 Infinity 被任何非零數(shù)值除,則結(jié)果是 Infinity-Infinity,取決于有符號操作數(shù)的符號;

如果有一個(gè)操作數(shù)不是數(shù)值,則在后臺調(diào)用 Number() 將其轉(zhuǎn)換為數(shù)值,然后再應(yīng)用上面的規(guī)則。

% 求模運(yùn)算符

用于計(jì)算兩個(gè)數(shù)值的余數(shù),與另外兩個(gè)乘性運(yùn)算符類似,求模運(yùn)算符會遵循下列特殊規(guī)則來處理特殊的值:

如果操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的除法計(jì)算,返回除得的余數(shù);

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

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

如果是 InfinityInfinity 除,則結(jié)果是 NaN;

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

如果被除數(shù)是零,則結(jié)果是零;

如果有一個(gè)操作數(shù)不是數(shù)值,則在后臺調(diào)用 Number() 將其轉(zhuǎn)換為數(shù)值,然后再應(yīng)用上面的規(guī)則。

加性運(yùn)算符

加法和減法這兩個(gè)加性運(yùn)算符應(yīng)該說是編程語言中最簡單的算術(shù)運(yùn)算符了。但是在 JavaScript 中,這兩個(gè)運(yùn)算符卻都有一系列的特殊行為。與乘性運(yùn)算符類似,加性運(yùn)算符也會在后臺轉(zhuǎn)換不同的數(shù)據(jù)類型。然而,對于加性運(yùn)算符而言,相應(yīng)的轉(zhuǎn)換規(guī)則還稍微有點(diǎn)復(fù)雜。

+ 加法運(yùn)算符

如果兩個(gè)運(yùn)算符都是數(shù)值,執(zhí)行常規(guī)的加法計(jì)算,然后根據(jù)下列規(guī)則返回結(jié)果:

如果有一個(gè)操作數(shù)是 NaN,則結(jié)果是 NaN;

如果是 InfinityInfinity,則結(jié)果是 Infinity;

如果是 -Infinity-Infinity,則結(jié)果是 -Infinity;

如果是 Infinity 加- Infinity,則結(jié)果是 NaN;

如果是 +0+0,則結(jié)果是 +0;

如果是 -0-0,則結(jié)果是 -0;

如果是 +0-0,則結(jié)果是 +0;

如果有一個(gè)操作數(shù)不是數(shù)值,那么就要應(yīng)用如下規(guī)則:

如果兩個(gè)操作數(shù)都是字符串,則將第二個(gè)操作數(shù)與第一個(gè)操作數(shù)拼接起來;

如果只有一個(gè)操作數(shù)是字符串,則將另一個(gè)操作數(shù)轉(zhuǎn)換為字符串,然后再將兩個(gè)字符串拼接起來。

如果有一個(gè)操作數(shù)是對象、數(shù)值或布爾值,則調(diào)用它們的 toString() 方法取得相應(yīng)的字符串值,然后再應(yīng)用前面關(guān)于字符串的規(guī)則。對于 undefinednull,則分別調(diào)用 String() 函數(shù)并取得字符串 "undefined""null"

如果是 nullnull,則結(jié)果是 0;

如果是 undefinedundefined,則結(jié)果是 NaN;

下面來舉幾個(gè)例子:

var result1 = 5 + 5;            // 兩個(gè)數(shù)值相加
console.log(result1);           // 10

var result2 = 5 + "5";          // 一個(gè)數(shù)值和一個(gè)字符串相加
console.log(result2);           // "55"

var num1 = 5;
var num2 = 10;
var message = "The sum of 5 and 10 is " + num1 + num2;
console.log(message);   // "The sum of 5 and 10 is 510",如何修改?
- 減法運(yùn)算符

如果兩個(gè)運(yùn)算符都是數(shù)值,執(zhí)行常規(guī)的減法計(jì)算,然后根據(jù)下列規(guī)則返回結(jié)果:

如果有一個(gè)操作數(shù)是 NaN,則結(jié)果是 NaN;

如果是 InfinityInfinity,則結(jié)果是 NaN

如果是 -Infinity-Infinity,則結(jié)果是 NaN;

如果是 Infinity-Infinity,則結(jié)果是 Infinity;

如果是 -InfinityInfinity,則結(jié)果是 -Infinity

如果是 +0+0,則結(jié)果是 +0;

如果是 +0-0,則結(jié)果是 -0

如果是 -0-0,則結(jié)果是 +0;

如果有一個(gè)操作數(shù)不是數(shù)值,那么就要應(yīng)用如下規(guī)則:

如果有一個(gè)操作數(shù)是字符串、布爾值、nullundefined,則先在后臺調(diào)用 Number() 函數(shù)將其轉(zhuǎn)換為數(shù)值,然后再根據(jù)前面的規(guī)則執(zhí)行減法計(jì)算。如果轉(zhuǎn)換的結(jié)果是 NaN,則減法的結(jié)果就是 NaN;

如果有一個(gè)操作數(shù)是對象,則調(diào)用對象的 valueOf() 方法以取得表示該對象的數(shù)值。如果得到的值是 NaN,則減法的結(jié)果就是 NaN。如果對象沒有 valueOf() 方法,則調(diào)用其 toString()方法并將得到的字符串轉(zhuǎn)換為數(shù)值。

如果是 nullnull,則結(jié)果是 0;

如果是 undefinedundefined,則結(jié)果是 NaN;

下面來舉幾個(gè)例子:

var result1 = 5 - true;         // 4,因?yàn)閠rue被轉(zhuǎn)換成了1
var result2 = NaN - 1;          // NaN
var result3 = 5 - 3;            // 2
var result4 = 5 - "";           // 5,因?yàn)?" 被轉(zhuǎn)換成了0
var result5 = 5 - "2";          // 3,因?yàn)?2"被轉(zhuǎn)換成了2
var result6 = 5 - null;         // 5,因?yàn)閚ull被轉(zhuǎn)換成了0
等值運(yùn)算符

確定兩個(gè)變量是否相等是編程中的一個(gè)非常重要的操作。在比較簡單數(shù)據(jù)類型之間的相等性時(shí),問題還比較簡單。但在涉及到對象之間的比較時(shí),問題就變得復(fù)雜了。最早的 JavaScript 中的相等和不等運(yùn)算符會在執(zhí)行比較之前,先將對象轉(zhuǎn)換成相似的類型。后來,有人提出了這種轉(zhuǎn)換到底是否合理的質(zhì)疑。最后,JavaScript 的解決方案就是提供兩組運(yùn)算符:相等和不相等(先轉(zhuǎn)換再比較),恒等和不恒等(僅比較而不轉(zhuǎn)換)。

== != 運(yùn)算符

== != 這兩個(gè)運(yùn)算符都會先轉(zhuǎn)換操作數(shù)(通常稱為強(qiáng)制轉(zhuǎn)型),然后再比較它們的相等性。在轉(zhuǎn)換不同的數(shù)據(jù)類型時(shí),相等和不相等運(yùn)算符遵循下列基本規(guī)則:

如果有一個(gè)操作數(shù)是布爾值,則在比較相等性之前先將其轉(zhuǎn)換為數(shù)值(false 轉(zhuǎn)換為 0,而 true 轉(zhuǎn)換為 1);

如果一個(gè)操作數(shù)是字符串,另一個(gè)操作數(shù)是數(shù)值,在比較相等性之前先將字符串轉(zhuǎn)換為數(shù)值;

如果一個(gè)操作數(shù)是對象,另一個(gè)操作數(shù)不是,則調(diào)用對象的 valueOf() 方法,用得到的基本類型值按照前面的規(guī)則進(jìn)行比較;

nullundefined 是相等的。
要比較相等性之前,不能將 nullundefined 轉(zhuǎn)換成其他任何值。

如果有一個(gè)操作數(shù)是 NaN,則相等運(yùn)算符返回 false,而不相等運(yùn)算符返回 true。重要提示:即使兩個(gè)操作數(shù)都是 NaN,相等運(yùn)算符也返回 false;因?yàn)榘凑找?guī)則,NaN 不等于 NaN。

如果兩個(gè)操作數(shù)都是對象,則比較它們是不是同一個(gè)對象。如果兩個(gè)操作數(shù)都指向同一個(gè)對象,則相等運(yùn)算符返回 true;否則,返回 false。

列出了一些特殊情況及比較結(jié)果:

null == undefined   // true
"NaN" == NaN        // false
5 == NaN            // false
NaN == NaN          // false
NaN != NaN          // true
false == 0          // true
true == 1           // true
true == 2           // false
undefined == 0      // false
null == 0           // false
"5" == 5            // true
=== !== 運(yùn)算符

除了在比較之前不轉(zhuǎn)換操作數(shù)之外,恒等和不恒等運(yùn)算符與相等和不相等運(yùn)算符沒有什么區(qū)別。它只在兩個(gè)操作數(shù)未經(jīng)轉(zhuǎn)換就相等的情況下返回 true,如下面的例子所示:

var result1 = ("55" == 55);     // true,因?yàn)檗D(zhuǎn)換后相等
var result2 = ("55" === 55);    // false,因?yàn)椴煌臄?shù)據(jù)類型不相等
var result3 = (null == undefined)   // true,因?yàn)樗鼈兪穷愃频闹?var result4 = (null === undefined)  // false,因?yàn)樗鼈兪遣煌愋偷闹?/pre>
關(guān)系運(yùn)算符

< > <= >= 運(yùn)算符

< 小于、> 大于、<= 小于等于、 >= 大于等于 這幾個(gè)關(guān)系運(yùn)算符用于對兩個(gè)值進(jìn)行比較返回一個(gè)布爾值。與 JavaScript 中的其他運(yùn)算符一樣,當(dāng)關(guān)系運(yùn)算符的操作數(shù)使用了非數(shù)值時(shí),也要進(jìn)行數(shù)據(jù)轉(zhuǎn)換或完成某些奇怪的操作。以下就是相應(yīng)的規(guī)則。

如果兩個(gè)操作數(shù)都是數(shù)值,則執(zhí)行數(shù)值比較。

如果兩個(gè)操作數(shù)都是字符串,則比較兩個(gè)字符串對應(yīng)的字符編碼值(可以通過字符串的 charCodeAt() 函數(shù)獲取字符編碼值)。

如果一個(gè)操作數(shù)是數(shù)值,則將另一個(gè)操作數(shù)轉(zhuǎn)換為一個(gè)數(shù)值,然后執(zhí)行數(shù)值比較。

如果一個(gè)操作數(shù)是對象,則調(diào)用這個(gè)對象的 valueOf() 方法,用得到的結(jié)果按照前面的規(guī)則執(zhí)行比較。如果對象沒有 valueOf()方法,則調(diào)用 toString()方法,并用得到的結(jié)果根據(jù)前面的規(guī)則執(zhí)行比較。

如果一個(gè)操作數(shù)是布爾值,則先將其轉(zhuǎn)換為數(shù)值,然后再執(zhí)行比較。

請思考下面幾個(gè)例子的結(jié)果是如何得出的:

var result1 = "Brick" < "alphabet";     // true
var result2 = "brick" < "alphabet";     // false
var result3 = "23" < "3";   // true
var result4 = "23" < 3;     // false
var result5 = "a" < 3;      // false
var result6 = NaN < 3;      // false
var result7 = NaN >= 3;     // false
in 運(yùn)算符

in 運(yùn)算符希望它的左操作數(shù)是一個(gè)字符串或可以轉(zhuǎn)換為字符串,希望它的右操作數(shù)是一個(gè)對象。如果右側(cè)的對象擁有一個(gè)名為左操作數(shù)值的屬性名,那么表達(dá)式返回 true,例如:

var point = { x:1, y:1 };       // 定義一個(gè)對象
"x" in point                    // true,對象有一個(gè)名為"x"的屬性
"z" in point                    // false,對象中不存在名為"z"的屬性
"toString" in point             // true,對象繼承了toString()方法

var data = [7,8,9];             // 擁有三個(gè)元素的數(shù)組
"0" in data                     // true,數(shù)組包含元素"0"
1 in data                       // true,數(shù)字轉(zhuǎn)換為字符串
3 in data                       // false,沒有索引為3的元素
instanceof 運(yùn)算符

instanceof 運(yùn)算符希望左操作數(shù)是一個(gè)對象,右操作數(shù)標(biāo)識對象的類。如果左側(cè)的對象是右側(cè)類的實(shí)例,則表達(dá)式返回 true;否則返回 false。后面會講 JavaScript 中對象的類是通過初始化它們的構(gòu)造函數(shù)來定義的。這樣的話,instanceof 的右操作數(shù)應(yīng)當(dāng)是一個(gè)函數(shù)。比如:

var d = new Date();     // 通過 Date() 構(gòu)造函數(shù)來創(chuàng)建一個(gè)新對象
d instanceof Date;      // true,d 是由 Date() 創(chuàng)建的
d instanceof Object;    // true,所有的對象都是 Object 的實(shí)例
d instanceof Number;    // false,d 不是一個(gè) Number 對象

var a = [1, 2, 3];      // 通過數(shù)組字面量的寫法創(chuàng)建一個(gè)數(shù)組
a instanceof Array;     // true,a 是一個(gè)數(shù)組
a instanceof Object;    // true,所有的數(shù)組都是對象
a instanceof RegExp;    // false,數(shù)組不是正則表達(dá)式

需要注意的是,所有的對象都是 Object 的實(shí)例。當(dāng)通過 instanceof 判斷一個(gè)對象是否是一個(gè)類的實(shí)例的時(shí)候,這個(gè)判斷也會包含對「父類」的檢測。如果 instanceof 的左操作數(shù)不是對象的話,instanceof 返回 false。如果右操作數(shù)不是函數(shù),則拋出一個(gè)類型錯(cuò)誤異常。

邏輯運(yùn)算符

邏輯運(yùn)算符是對操作數(shù)進(jìn)行布爾算術(shù)運(yùn)算,經(jīng)常和關(guān)系運(yùn)算符一起配合使用,邏輯運(yùn)算符將多個(gè)關(guān)系表達(dá)式組合起來組成一個(gè)更復(fù)雜的表達(dá)式。

&& 邏輯與

邏輯與操作可以應(yīng)用于任何類型的操作數(shù),而不僅僅是布爾值。在有一個(gè)操作數(shù)不是布爾值的情況下,邏輯與操作不一定返回布爾值;此時(shí),它遵循下列規(guī)則:

如果第一個(gè)操作數(shù)是對象,則返回第二個(gè)操作數(shù);

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

如果兩個(gè)操作數(shù)都是對象,則返回第二個(gè)操作數(shù);

如果有一個(gè)操作數(shù)是 null,則返回 null;

如果有一個(gè)操作數(shù)是 NaN,則返回 NaN;

如果有一個(gè)操作數(shù)是 undefined,則返回 undefined。

邏輯與操作屬于短路操作,即如果第一個(gè)操作數(shù)能夠決定結(jié)果,那么就不會再對第二個(gè)操作數(shù)求值。對于邏輯與操作而言,如果第一個(gè)操作數(shù)是 false,無論第二個(gè)操作數(shù)是什么值,結(jié)果都不再可能是 true 了。

|| 邏輯或

與邏輯與操作相似,如果有一個(gè)操作數(shù)不是布爾值,邏輯或也不一定返回布爾值;此時(shí),它遵循下列規(guī)則:

如果第一個(gè)操作數(shù)是對象,則返回第一個(gè)操作數(shù);

如果第一個(gè)操作數(shù)的求值結(jié)果為 false,則返回第二個(gè)操作數(shù);

如果兩個(gè)操作數(shù)都是對象,則返回第一個(gè)操作數(shù);

如果兩個(gè)操作數(shù)都是 null,則返回 null

如果兩個(gè)操作數(shù)都是 NaN,則返回 NaN;

如果兩個(gè)操作數(shù)都是 undefined,則返回 undefined。

與邏輯與運(yùn)算符相似,邏輯或運(yùn)算符也是短路運(yùn)算符。也就是說,如果第一個(gè)操作數(shù)的求值結(jié)果為 true,就不會對第二個(gè)操作數(shù)求值了。

! 邏輯非

邏輯非操作可以應(yīng)用于任何類型的操作數(shù),無論這個(gè)值是什么數(shù)據(jù)類型,這個(gè)運(yùn)算符都會返回一個(gè)布爾值。邏輯非運(yùn)算符首先會將它的操作數(shù)轉(zhuǎn)換為一個(gè)布爾值,然后再對其求反。邏輯非運(yùn)算符遵循下列規(guī)則:

如果操作數(shù)是一個(gè)對象,返回 false

如果操作數(shù)是一個(gè)空字符串,返回 true

如果操作數(shù)是一個(gè)非空字符串,返回 false

如果操作數(shù)是數(shù)值 0,返回 true

如果操作數(shù)是任意非 0 數(shù)值(包括 Infinity),返回 false;

如果操作數(shù)是 null,返回 true;

如果操作數(shù)是 NaN,返回 true;

如果操作數(shù)是 undefined,返回 true。

下面幾個(gè)例子展示了應(yīng)用上述規(guī)則的結(jié)果:

console.log(!false);          // true
console.log(!"blue");         // false
console.log(!0);              // true
console.log(!NaN);            // true
console.log(!"");             // true
console.log(!12345);          // false

邏輯非運(yùn)算符也可以用于將一個(gè)值轉(zhuǎn)換為與其對應(yīng)的布爾值。而同時(shí)使用兩個(gè)邏輯非運(yùn)算符,實(shí)際上就會模擬 Boolean() 轉(zhuǎn)型函數(shù)的行為。其中,第一個(gè)邏輯非操作會基于無論什么操作數(shù)返回一個(gè)布爾值,而第二個(gè)邏輯非操作則對該布爾值求反,于是就得到了這個(gè)值真正對應(yīng)的布爾值。當(dāng)然,最終結(jié)果與對這個(gè)值使用 Boolean() 函數(shù)相同,例如:

console.log(!!"blue");        //true
console.log(!!0);             //false
console.log(!!NaN);           //false
console.log(!!"");            //false
console.log(!!12345);         //true
位運(yùn)算符

在 JavaScript 中,當(dāng)對數(shù)值應(yīng)用位運(yùn)算符時(shí),后臺會發(fā)生如下轉(zhuǎn)換過程:64位的數(shù)值被轉(zhuǎn)換成32位數(shù)值,然后執(zhí)行位操作,最后再將32位的結(jié)果轉(zhuǎn)換回64位數(shù)值。這個(gè)轉(zhuǎn)換過程導(dǎo)致了一個(gè)嚴(yán)重的副效應(yīng),即在對特殊的 NaNInfinity 值應(yīng)用位操作時(shí),這兩個(gè)值都會被當(dāng)成 0 來處理。如果對非數(shù)值應(yīng)用位運(yùn)算符,會先使用 Number() 函數(shù)將該值轉(zhuǎn)換為一個(gè)數(shù)值,然后再應(yīng)用位操作,得到的結(jié)果將是一個(gè)數(shù)值。

~ 按位非

簡單的理解,對任一數(shù)值 x 進(jìn)行按位非操作的結(jié)果為 -(x+1)。例如:

console.log(~null);         // -1
console.log(~undefined);    // -1
console.log(~0);            // -1
console.log(~{});           // -1
console.log(~[]);           // -1
console.log(~(1/0));        // -1
console.log(~false);        // -1
console.log(~true);         // -2
console.log(~1.2543);       // -2
console.log(~4.9);          // -5
console.log(~(-2.999));     // 1
& 按位與

按位與操作就是將兩個(gè)數(shù)值的每一位對齊,兩個(gè)數(shù)值的對應(yīng)位都是 1 時(shí)才返回 1,任何一位是 0,結(jié)果都是 0。如下表所示:

第一個(gè)數(shù)值的位 第二個(gè)數(shù)值的位 結(jié)果
1 1 1
1 0 0
0 1 0
0 0 0
| 按位或

按位或操作就是將兩個(gè)數(shù)值的每一位對齊,兩個(gè)數(shù)值只要有一個(gè)位是 1 就返回 1,只在兩個(gè)位都是 0 的情況下才返回 0。如下表所示:

第一個(gè)數(shù)值的位 第二個(gè)數(shù)值的位 結(jié)果
1 1 1
1 0 1
0 1 1
0 0 0
^ 按位異或

按位異或與按位或的不同之處在于,兩個(gè)數(shù)值只有一個(gè) 1 時(shí)才返回 1,如果對應(yīng)的兩位都是 1 或都是 0,則返回 0。

第一個(gè)數(shù)值的位 第二個(gè)數(shù)值的位 結(jié)果
1 1 0
1 0 1
0 1 1
0 0 0
<< 左移

這個(gè)運(yùn)算符會將數(shù)值的所有位向左移動指定的位數(shù)。例如:

var oldValue = 2;                       // 等于二進(jìn)制的 10
var newValue = oldValue << 5;           // 等于二進(jìn)制的 1000000,十進(jìn)制的 64

注意,左移不會影響操作數(shù)的符號位。換句話說,如果將 -2 向左移動 5 位,結(jié)果將是 -64,而非 64。

>> 有符號的右移

這個(gè)運(yùn)算符會將數(shù)值向右移動,但保留符號位(即正負(fù)號標(biāo)記)。

var oldValue = 64;                      // 等于二進(jìn)制的 1000000
var newValue = oldValue >> 5;           // 等于二進(jìn)制的 10 ,即十進(jìn)制的 2
>>> 無符號的右移

這個(gè)運(yùn)算符會將數(shù)值的所有32位都向右移動。對正數(shù)來說,無符號右移的結(jié)果與有符號右移相同。

var oldValue = 64;                      // 等于二進(jìn)制的 1000000
var newValue = oldValue >>> 5;          // 等于二進(jìn)制的 10 ,即十進(jìn)制的 2

無符號右移運(yùn)算符會把負(fù)數(shù)的二進(jìn)制碼當(dāng)成正數(shù)的二進(jìn)制碼。而且,由于負(fù)數(shù)以其絕對值的二進(jìn)制補(bǔ)碼形式表示,因此就會導(dǎo)致無符號右移后的結(jié)果非常之大。

var oldValue = -64;                     // 等于二進(jìn)制的 11111111111111111111111111000000
var newValue = oldValue >>> 5;          // 等于十進(jìn)制的 134217726
賦值運(yùn)算符

簡單的賦值運(yùn)算符由等于號 = 表示,其作用就是把右側(cè)的值賦給左側(cè)的變量,如下面的例子所示:

var num = 10;

如果在等于號 = 前面再添加乘性運(yùn)算符、加性運(yùn)算符或位運(yùn)算符,就可以完成復(fù)合賦值操作。這種復(fù)合賦值操作相當(dāng)于是對下面常規(guī)表達(dá)式的簡寫形式:

var num = 10;
num += 10;      // 等同于 num = num + 10;

每個(gè)主要算術(shù)運(yùn)算符(以及個(gè)別的其他運(yùn)算符)都有對應(yīng)的復(fù)合賦值運(yùn)算符。這些運(yùn)算符如下所示:

乘/賦值 *=

除/賦值 /=;

模/賦值 %=

加/賦值 +=;

減/賦值 -=

左移/賦值 <<=;

有符號右移/賦值 >>=;

無符號右移/賦值 >>>=。

設(shè)計(jì)這些運(yùn)算符的主要目的就是簡化賦值操作,使用它們不會帶來任何性能的提升。

條件運(yùn)算符

? : 條件運(yùn)算符應(yīng)該算是 JavaScript 中最靈活的一種運(yùn)算符了,而且它遵循與 Java 中的條件運(yùn)算符相同的語法形式,如下面的例子所示:

variable = boolean_expression ? true_value : false_value;
逗號運(yùn)算符

逗號運(yùn)算符多用于聲明多個(gè)變量;但除此之外,逗號運(yùn)算符還可以用于賦值。在用于賦值時(shí),逗號運(yùn)算符總會返回表達(dá)式中的最后一項(xiàng),如下面的例子所示:

var num = (5, 1, 4, 8, 0); // num 的值為 0

由于 0 是表達(dá)式中的最后一項(xiàng),因此 num 的值就是 0。雖然逗號的這種使用方式并不常見,但這個(gè)例子可以幫我們理解逗號的這種行為。

關(guān)卡
// 挑戰(zhàn)一
var x=1;
if(!!function f(){}){
    x+=typeof f;
}
console.log(x);     // ???
// 挑戰(zhàn)二
(function f(f){
    console.log(typeof f());    // ???
})(function(){return 1;});
// 挑戰(zhàn)三
console.log(typeof 2*3);    // ???
console.log(typeof 2+3);    // ???
// 挑戰(zhàn)四
var a=0,b=0;
console.log(a+++b);     // ???
console.log(a);         // ???
console.log(b);         // ???
// 挑戰(zhàn)五
var a,b,c;
a=b==c;
console.log(a);     // ???
// 挑戰(zhàn)六
console.log(1 && 3);            // ???
console.log(1 && "foo" || 0);   // ???
console.log(1 || "foo" && 0);   // ???
// 挑戰(zhàn)七
var a=1;
var b=(a=(2,4,6))+a++
console.log(b);     // ???
// 挑戰(zhàn)八
if (!("a" in window)) {
    var a = 1;
}
console.log(a);     // ???
// 挑戰(zhàn)九
var val = "smtg"; 
console.log("Value is " + (val === "smtg") ? "Something" : "Nothing");  // ???
// 挑戰(zhàn)九
console.log(1 + - + + + - + 1);
更多

關(guān)注微信公眾號「劼哥舍」回復(fù)「答案」,獲取關(guān)卡詳解。
關(guān)注 https://github.com/stone0090/javascript-lessons,獲取最新動態(tài)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80144.html

相關(guān)文章

  • JavaScript 闖關(guān)

    摘要:對象數(shù)組初始化表達(dá)式,闖關(guān)記之上文檔對象模型是針對和文檔的一個(gè)。闖關(guān)記之?dāng)?shù)組數(shù)組是值的有序集合。數(shù)組是動態(tài)的,根闖關(guān)記之語法的語法大量借鑒了及其他類語言如和的語法。 《JavaScript 闖關(guān)記》之 DOM(下) Element 類型 除了 Document 類型之外,Element 類型就要算是 Web 編程中最常用的類型了。Element 類型用于表現(xiàn) XML 或 HTML 元素...

    mj 評論0 收藏0
  • JavaScript 闖關(guān)

    摘要:本課程之所以叫做闖關(guān)記,是因?yàn)椴糠终鹿?jié)精心設(shè)計(jì)了挑戰(zhàn)關(guān)卡,通過提供更多的實(shí)戰(zhàn)機(jī)會,讓大家可以循序漸進(jìn)地有目的地有挑戰(zhàn)地開展學(xué)習(xí)。課程結(jié)構(gòu)及目錄以下目錄只是初步構(gòu)想,課程結(jié)構(gòu)及內(nèi)容會根據(jù)實(shí)際情況隨時(shí)進(jìn)行調(diào)整。 為何寫作此課程 stone 主要負(fù)責(zé)基于 Web 的企業(yè)內(nèi)部管理系統(tǒng)的開發(fā),雖然能夠熟練地使用 JavaScript,但隨著對 JavaScript 的理解越來越深,才發(fā)現(xiàn)自己尚...

    curried 評論0 收藏0
  • JavaScript 闖關(guān)對象

    摘要:屬性名可以是包含空字符串在內(nèi)的任意字符串,但對象中不能存在兩個(gè)同名的屬性??蛻舳酥斜硎揪W(wǎng)頁結(jié)構(gòu)的對象均是宿主對象。這里的函數(shù)稱做構(gòu)造函數(shù),構(gòu)造函數(shù)用以初始化一個(gè)新創(chuàng)建的對象。通過關(guān)鍵字和構(gòu)造函數(shù)調(diào)用創(chuàng)建的對象的原型就是構(gòu)造函數(shù)的屬性的值。 對象是 JavaScript 的數(shù)據(jù)類型。它將很多值(原始值或者其他對象)聚合在一起,可通過名字訪問這些值,因此我們可以把它看成是從字符串到值的映射...

    rozbo 評論0 收藏0
  • JavaScript 闖關(guān)簡介

    摘要:瀏覽器只是實(shí)現(xiàn)的宿主環(huán)境之一,其他宿主環(huán)境包括和。年月,版發(fā)布,成為國際標(biāo)準(zhǔn)。事件定義了事件和事件處理的接口。對于已經(jīng)正式納入標(biāo)準(zhǔn)的來說,盡管各瀏覽器都實(shí)現(xiàn)了某些眾所周知的共同特性,但其他特性還是會因?yàn)g覽器而異。 JavaScript 是面向 Web 的編程語言,絕大多數(shù)現(xiàn)代網(wǎng)站都使用了 JavaScript,并且所有的現(xiàn)代 Web 瀏覽器(電腦,手機(jī),平板)均包含了 JavaScri...

    baihe 評論0 收藏0
  • JavaScript 闖關(guān)函數(shù)

    摘要:把上面的函數(shù)聲明改為等價(jià)的函數(shù)表達(dá)式,就會在執(zhí)行期間導(dǎo)致錯(cuò)誤。換句話說,引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對象當(dāng)在網(wǎng)頁的全局作用域中調(diào)用函數(shù)時(shí),對象引用的就是。這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi)對象的值。 函數(shù)是一段代碼,它只定義一次,但可以被執(zhí)行或調(diào)用任意次。在 JavaScript 里,函數(shù)即對象,程序可以隨意操控它們。比如,可以把函數(shù)賦值給變量,或者作為...

    alphahans 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<