運算子
數學運算子的正統,number和number的數學運算,結果是number。出於面試的考慮,有一些奇奇怪怪的數學運算:
數學運算中:只有純字串、布林值、null能夠進行隱式轉換。
//隱式轉換:就是沒有寫parseInt()、parseFloat()也能自動幫你轉換型別 console.log(2 + "4"); //24 console.log(26 - "2"); //24 console.log(3 * "8"); //24 console.log("3" * "8"); //24 console.log("48" / "2"); //24 console.log("24" % 25); //24 console.log(3 * null); // 0 隱式轉換時null被轉換為0 console.log(3 * false); // 0 隱式轉換時false被轉換為0 console.log(3 * true); // 3 隱式轉換時true被轉換為1 console.log(3 + true); // 4 隱式轉換時true被轉換為1 console.log(3 + false); // 3 隱式轉換時false被轉換為0 console.log(3 + null); // 3 隱式轉換時null被轉換為0 console.log(3 - false); // 3 隱式轉換時false被轉換為0 console.log(3 - null); // 3 隱式轉換時null被轉換為0 console.log(3 - ""); // 3 隱式轉換時""被轉換為0
不純的字串和undefined是不能進行隱式轉換,結構都是NaN:
console.log(3 * "8天"); //NaN 數學中,不純的字串沒法隱式轉換 console.log(3 * undefined); //NaN 數學中,undefined沒法隱式轉換 console.log(3 + undefined); //NaN 數學中,undefined沒法隱式轉換 console.log(3 - undefined); //NaN 數學中,undefined沒法隱式轉換 console.log(3 / undefined); //NaN 數學中,undefined沒法隱式轉換
加法比較特殊,因為“+”號同時是加法和拼接字串的符號,所以加法在面對字串的時候沒有隱式轉換。
console.log(2 + "4"); //24 |
總結:
無論哪種運算,只要出現了undefined參與運算,結果都是NaN。
然後字串"8"、false、true、null都能進行隱式轉換。
加號比較特殊,面對字串"8"沒有隱式轉換的
特殊值數值的計算:NaN、Infinity參與的運算。
Infinity參與的運算:
console.log(Infinity + 1000); //Infinity console.log(Infinity - 1000); //Infinity console.log(Infinity * 1000); //Infinity console.log(Infinity / 1000); //Infinity console.log(Infinity + Infinity); //Infinity console.log(Infinity * Infinity); //Infinity console.log(Infinity - Infinity); //NaN console.log(Infinity / Infinity); //NaN console.log(9 / 0); //Infinity console.log(0 / 0); //NaN
NaN參與運算:得到結果都是NaN
console.log(NaN + 2);//NaN console.log(NaN - 2);//NaN console.log(NaN * 2);//NaN console.log(NaN / 2);//NaN console.log(NaN % 2);//NaN
特殊值的數學運算,防止被大公司面試陰,要過一下腦。不過數學運算的特殊值,沒有任何的實戰價值,建議沒必要刻意記憶,留著腦容量記更有用。
一.比較運算子
比較運算子介紹:
比較運算子(關係運算子)的正統,number和number的數學運算,比較它的運算元會返回一個Boolean布林型別的值。要麼是true(真),要麼是false(假)
> 大於 < 小於 >= 大於或等於 <= 小於或等於 == 相等,判斷值相等,不會判斷資料型別 ====全等於,除了判斷數值是否相等,還要判斷資料型別是否相等 != 不等於,取反,永遠和相等判斷相反 !== 不全等,取反,永遠與全等於判斷相反 |
1.1正常情況下:數學和數字進行比較
console.log(5 > 6); //false console.log(5 < 6); //true console.log(5 <= 6); //true console.log(5 >= 6); //false console.log(5 == 5); //true console.log(5 === 5);//true console.log(5 != 5); //false console.log(5 !== 5);//false |
==叫做"相等判斷",不會判斷資料型別,它會進行隱式轉換,儘可能得到true的答案:
console.log(5 == "5"); //true |
===叫做"全等於",會比較數值是否相等,還會判斷資料型別是否相等:
console.log(5 === "5"); //false |
!=是==的反面,如果==運算是true,那麼!=是false
!==是===的反面,如果===運算是true,那麼!==是false
console.log(5 != "5"); //false,腦子要反著想,5 == "5"結果是true,取反後是false console.log(5 !== "5"); //true,腦子要反著想,5 === "5"結果是false,取反後是true |
正統的講完了,number和number進行比較運算,結果都是Boolean。
1.2不正統的比較運算:
1、string和string也能進行比較運算,比較的是字元編碼順序(Unicode)。
字元編碼順序:0~9、A~Z、a~z,順序越往後越大。
比較多個字串:從左往右,一個一個的比較,直到比較出大小,就終止比較。
console.log("a" < "b"); //true console.log("A" < "B"); //true console.log("A" < "a"); //true 大寫字母在字符集中是在小寫字母前面 console.log("1" < "A"); //true 數字在字母的前面 console.log("blank" < "blue"); //true 一位一位比較,直到比出大小,就結束比較,後面的忽略。 console.log("23" < "3"); //true,因為String和String比的不是數字,而是字元編碼順序
2、與數字進行比較運算時,純數字字串會被轉為數字,null轉換0,false轉換0,true轉換1
null不能進行和0相等判斷。
console.log(null < 0.0001); //true console.log(null > -0.0001); //true console.log(null >= 0); //null轉化為number,為0>=0,所以結果為true console.log(null <= 0); //null轉化為number,為0<=0,所以結果為true console.log(null > 0); //null轉化為number,為0,所以0>0結果為false。 console.log(null == 0);//null在==判斷時,不進行轉型,所以null和0為不同型別,結果為false。 console.log(false == 0); //true console.log(true == 1); //true
3、String和number比,string會被隱式轉換為number
非正常情況:數字與其他資料比較,其他資料之間進行轉換(忽略字串與字串比較)
"123" → 123 、true → 1 、 false → 0 、undefined → NaN 、"hello" → NaN、"" → 0 |
舉例:
console.log(1 < ""); //false console.log(0 == ""); //true console.log(0 == "hello"); //false console.log(0 == undefined); //false console.log(1 < "2"); //true console.log(0 === ""); //false console.log(1 == true); //true console.log(0 == false); //true console.log(0 == false); //true
4、特殊值參與比較:NaN、Infinity
NaN參與:NaN不等於自己,也不全等於自己。
console.log(NaN == NaN); //false console.log(NaN === NaN); //false console.log(NaN != NaN); //true console.log(NaN !== NaN); //true console.log(NaN < 0); //false console.log(NaN >= 0); //false console.log(NaN != 0); //true
Infinity :
console.log(Infinity > 100); //true console.log(Infinity >= 100); //true console.log(Infinity < 100); //false console.log(Infinity <= 100); //false console.log(Infinity == 100); //false console.log(Infinity != 100); //true
Infinity與自身比較:
console.log(Infinity > Infinity); //false console.log(Infinity >= Infinity); //true console.log(Infinity < Infinity); //false console.log(Infinity <= Infinity); //true console.log(Infinity == Infinity); //true console.log(Infinity === Infinity);//true console.log(Infinity != Infinity); //false console.log(Infinity !== Infinity);//false
需要注意的是,我們已經瞭解一些不正統的運算,所以不要出洋相,不能連續使用比較運算子。
比如像驗證3大於2,2大於1
3 > 2 > 1; //false |
解:原式 (3>2)= true > 1 = false。(因為true被轉為1來與1進行比較)
也就是說,不能連續使用比較運算子,一旦使用了連續的,實際上是從左到右計算,所以就有上一步的布林型別值參與下一步的運算。
二.邏輯運算子
邏輯運算子常用於布林型別值之間,當運算元都是布林值的時候,返回值也是布林值。
&& 邏輯“與”運算子,交集,兩個條件都成立才為真 || 邏輯“或”運算子,並集,只要其中一個成立就為真 ! 邏輯“非”運算子 |
2.1邏輯“與”&& 運算子
正統來說,參與邏輯運算的都是Boolean和Boolean型別,得到的結果也是Boolean型別值。
按照真值表來定: &&邏輯與(且)
a && b |
||
a |
b |
結果 |
真 |
真 |
真 |
真 |
假 |
假 |
假 |
真 |
假 |
假 |
假 |
假 |
結論:“都真才真”,“有假就假”。
命題1:“地球是圓的” 真的 命題2:“習大大是男的” 真的 命題1 && 命題2 = 真 |
命題1:“1+1=2” 真的 命題2:“地球是方的” 假的 命題1 && 命題2 = 假 |
邏輯運算子“與”
console.log(true && true); //true console.log(true && false); //false console.log(false && true); //false console.log(false && false); //false
2.2邏輯“或”|| 運算子
按照真值表來定: ||邏輯“或”
a || b |
||
a |
b |
結果 |
真 |
真 |
真 |
真 |
假 |
真 |
假 |
真 |
真 |
假 |
假 |
假 |
結論:“有真就真”,“都假就假”。
命題1:“地球是圓的” 真的 命題2:“習大大是男的” 真的 命題1 || 命題2 = 真 |
命題1:“1+1=2” 真的 命題2:“地球是方的” 假的 命題1 || 命題2 = 真 |
2.3邏輯“非”!
!就是邏輯“非”,相反的,非真即假,非假即真。
console.log(!true); //false console.log(!false); //true console.log(!!!!!false); //true |
2.4 邏輯運算子-短路語法
短路語法就是將“邏輯與”、“邏輯或”模擬成電路短路的效果。
非正常情況:布林型別的值或其他型別的值進行混合邏輯運算,運算過程中其他的資料型別會隱式轉換為布林型別的值,運算完之後返回值不一定是布林值,而是對應的位置的某個具體值。
隱式轉換為false有:null、0、NaN、空字串("")、undefined
隱式轉換為true有:除了以上5種,全是真。
2.4.1邏輯“&&”的短路語法
電流先通過a:
如果a為真,能走到b,不論b為真還是假,直接輸出b的結果。
如果a為假,電流不通,直接留在a,不管b是什麼,直接把a作為結果輸出。
也就是說,本質上計算機進行a && b運算時,不是在進行邏輯分析,要麼輸出a,要麼輸出b。如果a是假的,直接輸出a;如果a是真的,直接輸出b。
-----短路語法,要麼被a短路,要麼被b短路。
console.log(false && 8); //false,且運算a已經是false,直接輸出false console.log(true && 8); //8,且運算a已經是true,電流通了,可以走到b,將b作為結果輸出 console.log(null && 8); //null 且運算a已經是false,直接輸出a的結果 console.log(12 && 13); //13 且運算a已經是true,電流通了,可以走到b,將b作為結果輸出 console.log(true && NaN); //NaN console.log(undefined && 哈哈); //undefined console.log("哈哈" && undefined); //undefined console.log("" && undefined); // "" //console.log(哈哈 && undefined); //報錯
2.4.2邏輯“||”的短路語法
總結:
如果a為真,直接得到a結果
如果a為假,直接得到b結果(換線路走b,不論b真假)
console.log(false || null); //null console.log(true || null); //true console.log(123 || "哈哈"); //123 console.log(0 || 18); //18 console.log(18|| 0); //18 console.log(undefined || NaN);//NaN
運算順序:非(!)、與(&&)、或(||)
true || false && !true || false |
原式:= true || false && !true || false
= true || false && false || false
= true || false || false
= true || false
= true
88 || 99 && 66 || 55 |
原式:= 88 || 99 && 66 || 55
= 88 || 66 || 55
= 88 || 55
= 88
undefined && ("3" != 3) || NaN && null |
原式:= undefined && false || NaN && null
= undefined || NaN && null
= undefined || NaN
= NaN
綜合運算順序題目:非(!)、與(&&)、或(||)
null && true || undefined && 123 || !"hello" && fasle |
原式:= null && true || undefined && 123 || !"hello" && fasle
= null && true || undefined && 123 || false && fasle
= null || undefined && 123 || false && fasle
= null || undefined || false && fasle
= null || undefined || false
= undefined || false
= false
//短路語法案例:以後經常會遇見這種套路 var age = parseInt(prompt("請輸入年齡")); (age >= 18) && alert("已經成年,可以考駕照"); (age < 18) && alert("未成年,可以做違法的事情");
總結短路語法:
當它們用於非布林值的時候,返回值可能是非布林值,其實這種運算很簡單,就兩句話:
a && b 如果a為真,執行b a || b 如果a為真,執行a |
不推薦背誦規律:自己去推導過程(短路語法)。
三.賦值運算子
賦值運算子必須有變數參與。
= 簡單的賦值,不需要運算 += 加等於 -= 減等於 /= 除等於 *= 乘等於 %= 取餘等於 ++ 每次在原基礎上加1 -- 每次在原基礎上減1 |
var a = 1; a += 2; //這行語句等價於a = a + 2; console.log(a); var b = 6; b /= 3; //這行語句等價於b = b / 3; console.log(b); //2 var c = 1; c *= 2; //這行語句等價於c = c * 2; console.log(c); //2 var d = 100; d -= 50; //這行語句等價於d = d - 50; console.log(d); //50 var e = 100; e %= 10; //這行語句等價於e = e % 10; console.log(e); //0 var f = "大"; f += "家"; //這行語句等價於f = f + "家"; f += "好"; console.log(f);
++運算子:
++可以與輸出語句寫在一起,++寫在變數前和變數後不是一個意思。
a++ : 先用a的原值,然後a再加1 ++a :先給a加1,然後再給a賦新值 |
var g = 10; console.log(g++); //10 先引用原值,再加1 console.log(g); //11,用了g++後的值 |
等價於:
var f = 10; console.log(f); //先輸出f f++; //然後f加1 |
var h = 10; console.log(++h);//11,這是自加1,再輸出 |
++有花式玩法,僅面試有用:
var z = 8; console.log(4 + z++); //12,先用原來的z值,4 + 8,輸出12然後再加1 |
var y = 9; console.log(++y % 5); //0,先把y加1,然後使用i,10 % 5 = 0 |
綜合案例:
var a = 10; var b = 20; var c = 30; var sum = a++ + ++b + c++ + ++a + ++c; // 10 + 21 + 30 + 12 + 32 = 105 console.log(a) console.log(b) console.log(c) console.log(sum)
綜合運算順序
運算子的計算順序:
貼身(! ++ --) → 數學運算子 → 比較運算子 → 邏輯運算子 → 賦值運算子 |
var a = 3 < 6 && 7 < 14; |
原式 = true && true
= true
var b = 1 + 2 < 3 + 3 && 3 + 4 < 2 * 7 |
原式:= 1 + 2 < 3 + 3 && 3 + 4 < 2 * 7
= 3 < 6 && 7 < 14
= true && true
= true
var c = false + true && 13; |
原式: = 0 + 1 && 13
= 1 && 13
= 13
var a = 15; false + a++ + true > 8 && 13 || 6 |
原式 = false + 15 + true > 8 && 13 || 6
= 16 > 8 && 13 || 6
= true && 13 || 6
= 13 || 6
= 13
四.if條件分支語句
流程控制語句:可以利用一些結構打斷程式,或者挑選分支執行,或者迴圈執行某一段語句。
包含:條件分支語句、迴圈語句
條件分支語句:if語句、switch語句、三元運算子
4.1 if語句
if(條件表示式){ 條件表示式成立執行 } |
if(條件表示式){ 條件表示式成立執行 }else{ 條件表示式不成立執行 } |
if 如果
else 否則
條件表示式,可以是任意內容,表示式會強制得到一個布林值,只要表示式在參與程式之前都會計算出一個結果。根據布林型別結果的真假,選取分支。
if語句只會選一個分支進行執行,另一個不執行:
var num = 80; if(num >= 60){ alert("及格"); }else{ alert("不及格"); } if(8 > 10){ alert("條件成立"); }else{ alert("條件不成立"); }
//使用者輸入密碼 var pwd = parseInt(prompt("請輸入您的密碼")); //返回使用者資訊,是否正確 if(pwd == 123456){ alert("密碼正確"); }else{ alert("密碼錯誤"); }
如果結構體中只有單行語句,可以省略大括號:
var pwd = parseInt(prompt("請輸入您的密碼")); //返回使用者資訊,是否正確 if(pwd == 123456) alert("密碼正確"); else alert("密碼錯誤"); alert("請再次輸入"); //超出else的控制範圍,所以會執行
4.2多條件if語句
根據多個條件可以選擇不同的支進行執行。
語法:if...else if...else if
如果...否則如果...否則如果..否則
if(條件表示式1){ 條件表示式1成立,執行的結構體1 }else if(條件表示式2){ 條件1為假,條件2為真,執行的結構體2 }else if(條件表示式3){ 條件1、2為假,條件3為真,執行的結構體3 }else{ 以上的條件都為假,執行這裡的結構體 }
【注意】:
1、多條件if語句可以有多個else if,但是隻能有一個else。else也可以省略。前面的條件有滿足的直接選擇分支,如果都不滿足,就直接跳出if語句執行後面其他的程式碼。
var s = parseInt(prompt("請輸入成績")); if(s >= 90){ alert("優秀!棒棒噠"); }else if(s >= 80){ alert("良好!繼續保持"); }else if(s >= 70){ alert("中等!繼續努力"); }else if(s >= 60){ alert("及格"); }
2、跳樓現象:if語句選中了某個複合條件的分支,執行完結構體後,不管執行結果如何,都會直接跳出if語句。不再往下繼續判斷。
var a = 3; if(a < 5){ a += 5; //滿足第一個條件,執行完後,不會再繼續往下判斷,直接跳樓 }else if(a == 8){ a + 3; }else if(a % 3 == 2){ a += 5; }else{ a += 12; } console.log(a); //8
if語句不管是普通的還是多分支的,都只會選一個分支,然後跳樓,殊途同歸執行if後面的語句。
4.3 if語句巢狀
if語句的結構體可以再巢狀if語句
如果想執行內部的if語句的某個分支,除了要滿足自身條件之外,還要滿足外層條件。
var sex = prompt("請輸入性別"); var age = parseInt(prompt("請輸入年齡")); if(sex == "男" && age >= 22){ alert("可以結婚了"); }else if(sex == "男" && age < 22){ alert("你還小,先去網咖轉轉!"); }else if(sex == "女" && age >= 20){ alert("菇涼,可以嫁人了"); }else if(sex == "女" && age < 20){ alert("不能結婚,不要著急"); }else{ alert("你是人妖嗎?") }
if(sex == "男"){ //只要進來執行,性別肯定是男的 //判斷年齡是否大於或等於22 if(age >= 22){ alert("恭喜,小鮮肉可以結婚了"); }else{ alert("不能結婚,再堅持一會!") } }else if(sex == "女"){ if(age >= 20){ alert("恭喜,小姐姐可以結婚了"); }else{ alert("小蘿莉不能結婚,再堅持一會!") } }else{ //進入這個條件分支語句,說明不是男也不是女,是人妖 alert("人妖走開!"); }