顯示廣告
隱藏 ✕
看板 KnucklesNote
作者 Knuckles (站長 那克斯)
標題 [JS] 克服JS的奇怪部分 ch3 型別與運算子
時間 2016-11-23 Wed. 00:53:15


Udemy課程: JavaScript全攻略:克服JS的奇怪部分
https://www.udemy.com/javascriptjs/learn/v4/overview
上完第三章的心得筆記

章節3 型別與運算子

19. 觀念小叮嚀:型別與 JavaScript

動態型別(Dynamic Typing): JS的變數不用預先設定是什麼型別,會在執行時自動判別


20. 純值(Primitive Types,或稱基本型別)

基本型別: 只代表一個值的資料 (非物件的意思,物件是名稱/值的組合)

JS有種六種基本型別:

undefined: 代表未定義,剛建立的變數還沒賦值時,其值就是 undefined
           不建議將變數設定為這個值

null: 代表不存在,要設定變數的值不存在時,可指定為 null,不要指定為 undefined

boolean: 只有兩個值 true 或 false

number: 含有小數的數字,不像其他語言有分整數和浮點數,JS的數字型別就只有number

string: 字串,可用單引號''或雙引號""來表示

symbol: 在 ES6(下一版JS) 才有,瀏覽器還沒有都支援


21. 觀念小叮嚀:運算子(Operator)

運算子其實也是函數的一種

例如 var a = 4 + 3; 可以看成是 var a = +(4,3);

+號是一個輸入前後兩個參數,輸出兩個參數相加結果的函數


22. 運算子的優先性(Precedence)與相依性(Associativity)

一行程式中有多個運算子時,先做優先性高的運算子
優先性相同的話再依相依性看要從左到右,還是從右到左

可以在 MDN(Mozilla Developer Network) 的網站查看 各種運算子優先性與相依性表格
[圖]



24. 觀念小叮嚀:強制型轉(Coercion)

因為JS的變數是動態型別,不同型別的值,使用運算子計算時,
會先強制將型別轉為相同的再做運算

例如 var a = 1 + '2';

將一個數字1與字串'2'相加時,JS會先將數字1轉為字串'1'
+號變成字串相連的運算子,輸出為 '12'


25. 比較運算子

console.log(1 < 2 < 3); // 顯示 true
console.log(3 < 2 < 1); // 顯示 true
第一行好像合理,但為何第二行也是 true 呢?

因為 < 運算子的相依性為左到右, 3 < 2 會先輸出 false,變成 false < 1
而 false 會強制型轉為數字 0,變成 0 < 1
所以最後會輸入 true

可以使用 Number() 這個內建函數測試強制型轉為數字會變什麼
Number(true);  // 輸出 1
Number(false); // 輸出 0
Number('3');   // 輸出 3
Number(undefined) // 輸出 NaN
Number(null)      // 輸出 0

NaN 不是個型本型別,代表有個東西無法轉成數值型別的結果

undefined 無法轉為數值,但 null 卻可以,容易造成未預期的結果

使用比較運算子,尤其是==時,容易出現未預期的結果
"3" == 3    // 輸出 true
false == 0  // 輸出 true
null == 0   // 輸出 false
null < 1    // 輸出 true
"" == 0     // 輸出 true
"" == false // 輸出 true

所以沒特別需求時,要比較變數是否相同時一律改用 ===
強制型別相同且值也相同時才會輸出 true

要判斷不相等時改用 !==

可參考MDN的 相等性比較表格
有列出了各種型別使用 == 與 === 的輸出結果


27. 存在與布林

使用內建函數 Boolean() 來判斷各種型別轉為 boolean 的結果
Boolean(undefined)    // 輸出 false
Boolean(null)         // 輸出 false
Boolean("")           // 輸出 false
可發現各種代表沒有的值,都會輸出 false

所以可以利用強制型轉的特性,用if來判斷是否有取得值
var a;

// 從網路上取得某個值存到 a

if(a){
	
console.log('a 有取得某個值');
}

很多框架有利用這個特性來設計

但要注意 Boolean(0) 也是輸出 false
所以取得的值有可能是數字 0 的話,要改為
var a;

// 從網路上取得某個值存到 a

if(a || a === 0){
	
console.log('a 有取得某個值');
}


28. 預設值

當函數需要輸入值,但呼叫的時候沒有輸入的時候,例如
function greet(name){
	
console.log('Hello ' + name);
}

greet('Tony');// 顯示 Hello Tony
greet();      // 顯示 Hello undefined

沒有給輸入值時,JS不會出現錯誤
name就變成一個有建立但沒有賦值的變數,預設的值就是 undefined
但 undefined 被轉為字串 'undefined' 顯示出來,不是我們想要的結果

如果想要在JS函數的輸入值設定預設值的話,可以這樣寫
function greet(name){
	
name = name || '<Your name here>';
	
console.log('Hello ' + name);
}

greet('Tony');// 顯示 Hello Tony
greet();      // 顯示 Hello <Your name here>

這是利用了 || 運算子的特殊行為
當輸入了兩個可以被轉型為boolean的值,會輸出第一個被轉型為true的值
undefined || "hello"  // 輸出 "hello"
"hi" || "hello"       // 輸出 "hi"
0 || 1                // 輸出 1
null || "hello"       // 輸出 "hello"
"" || "hello"         // 輸出 "hello"

要注意輸入值若是數字 0 的時候也會被當成未輸入


29. 框架小叮嚀:預設值

當網頁載入其他JS程式時,常會需要在全域環境加入新的全域變數
若這個全域變數在原本的JS程式就有用到時,可能就會把本來的值蓋掉了

例如原本的程式有
var libraryName = "lib 1";

新加入的程式若寫成
var libraryName = "lib 2";

就會把本來程式的值蓋掉了,造成未預期的結果

所以可以前面設定預設值的技巧

需要建立新的全域變數時,改為使用
window.libraryName = window.libraryName || "Lib 2";

若原本已經有這個變數且有賦值了,就用原本的
沒有的話再建立並設為新的值

--
※ 作者: Knuckles 時間: 2016-11-23 00:53:15
※ 編輯: Knuckles 時間: 2016-11-23 03:46:08
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 1448 
分享網址: 複製 已複製
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇