# Javascript 第二章 變數、值與型別
###### tags: `JS X Codeshiba`
## 變數的資料型別
**「變數」** 本身不帶有資料型別的資訊
**「值」** 或是 **「物件」** 才會有
所以執行時期透過變數內容來參考物件或值,才會得知如此變數有甚麼可以操作的方法
一般來說,我們應該優先使用常數而不是變數,這樣比較物容易無意間改變某些不該改變的值
變數通常會用在迴圈的部分,因為數值會隨之變動
## 變數的型別分類
1. 基本型別(Primitives)
string, number, boolean, null, undefined, symbol
2. 物件型別(Object)
## 識別碼與常值
識別碼: 變數與常數的名稱,稱為識別碼
常值: 建立值的方式,JS會接受提供的長值,用來建立一個資料值
```javascript=
let room = "conference_room_a"
// room1 識別碼
// "conference_room_a" 為常值
```
打開瀏覽器,使用`ctrl+shift+i`來開啟開發人員檢查的介面
使用`console`來輸入Javascript

可以使用`var`或`let` 來宣告變數,但let只能宣告一次
**那麼var跟let**,用哪個好呢?
之後我決定都用let與const好了,會比var還要嚴謹
[參考資料: var](https://something-about-js-book.onejar99.com/day07)
[參考資料: let](https://something-about-js-book.onejar99.com/day08)
```javascript=
var x;
x = 15;
```

在程式語言的世界裡,"="是指派的意思

使用typeof就可以知道變數的型別

## 用console.log在網頁上觀察變數

## 浮點數的陷阱

## 字串的宣告法
可以使用下列方法來做宣告
```javascript=
var str = "這是一個字串";
var str2 = '這是一個字串';
```
使用跳脫字元(反斜線)就可以避免符號的錯誤
```javascript=
var a = '
let\'s Go!!'
console.log(a);
```

使用+號即可連接字串
```javascript=
var a = 'YoYo!!'+' '+'Who\'s this guy?'
console.log(a);
```

使用反斜線就可以連結字串
```javascript=
var a = 'Hey! I love your\
I am really love your\
It\'s True!!';
console.log(a);
```

在JS裡面,字串代表`Unicode`文字,可以用單引號、雙引號或是反引號來表示,反引號是ES6裡面啟用`樣板字串`(template strings)的手法
## 數值的宣告法
數值的宣告相當親民,但是有些特定的數值會被下列的方式計算出來,例如Infinity
```javascript=
var a = 0
var b = 1
console.log(a/b); //是0
console.log(b/a); //是Infinity
console.log(0-b/a); //是-Infinity
```

### NaN的存在
無法運算的數值就會顯示NaN
NaN字面上不是數字,但typeof又會告訴我們是Number
直接透過 === 來判斷一個值是否為NaN又不大適合
```Example
a = NaN;
b = NaN;
console.log(a === b);
```

### NaN的判定法 isNaN
透過下面範例可以看到,isNaN的判定效果是準確的
```Example
c = isNaN(a);
d = isNaN(b);
e = isNaN(123);
console.log(c);
console.log(d);
console.log(e);
```

### 如何判定浮點數
因為10進位的小數無法用2進位來完美呈現,所以會需要透過下列方法來判定
```
console.log(0.1+0.2 === 0.3);
console.log(Math.abs(0.1+0.2-0.3)<=Number.EPSILON);
```

## Boolean值
有些語言(例如C語言)會使用數字來取代布林值,Javascript可以讓任何值都被視為布林值(true or false),還有就是字串的`'false'`其實為`true`
```javascript=
let heating = true;
let cooling = false;
```
## Undefined & Null
兩者都只有一種值(Null & Undefined),都是代表某種不存在的東西
**一般來說**,你應該用null的資料型態,把undefined留給JS來使用,來指出哪些東西應該還沒有被賦值
1. Undefined
宣告了變數,卻沒有丟給它任何東西

2. Null
指定它為空值

```javascript=
let currentTemp; //隱含undefined值
const targetTemp = null; //目標溫度null -- "還不知道"
currentTemp = 19.5; //現在currentTemp有值了
currentTemp = undefined; // currentTemp就像還未被初始化
//不建議使用此種做法
```
### 特例
在非全域作用範圍下,undefined允許被當成變數名稱使用
但還是別亂用啦...

## 符號
ES6新增的功能,是一種新的資料型態,表示獨一無二的標記
1. 建立符號時,他是唯一的
2. 不會匹配其他符號,就像物件一樣(物件就是唯一的)
3. 具有擴充性
4. 符號是用Symbol的建構式來建立的
5. 如果想要建立獨一無二的識別碼,並避免跟其他的識別碼混淆,可以選擇符號
```javascript=
const RED = Symbol();
const ORANGE = Symbol("The color of a sunset");
RED === ORANGE //false: 每一個符號都是唯一的
```
## 變數名稱的違例
1. 不可以用數字當開頭
2. 不可以有其他特殊字元當開頭(除了$或_)
## 變數名稱的命名原則
1. 變數: 採用駝峰型(e.g. numCakeDonuts)
2. 常數: 全部大寫(e.g. TAXRATE)
## 註解&資料類型
``` Example1
// 單行註解
```
``` Example2
/* 多行註解
*/
```
``` Example3
數字 15
浮點數 15.555
字串 "這是字串"
布林值 true;false
物件 很複雜!...
```
### 單元運算
``` 範例
var result=15-15;
alert(result);
result++; //等於是 result=result+1
alert(result);
```
### 比較運算
```Example
result=4>3
alert(result);
```
因為4>3,就會跑出True
### 輸入&輸出
流程
```Example
輸入->程式運算->alert(運算)
```
prompt(提示語,預設值) -> 程式運算 -> 輸出: alert(資料);
```Example
var nl=prompt("請輸入數字","1");
```
就會出現視窗,並且讓使用者可以輸入,並且把內容做成變數
## 流程控制-判斷式
```Example
if (判斷) {
若判斷的結果是正確的(true),則執行大括號區塊中的程式碼。
反之(false),則忽略此區塊。
}
```
```Example
if (true){
alert("Hello World");
}
```
```Example
var money=prompt("要提多少錢?","")
if(money>30000){
alert("不能提那麼多錢");
}
```Example
if (判斷){
若判斷的結果是正確的(true),則執行大括號區塊中的程式碼。
}else{
若判斷是錯誤的(false),則執行else大括號區塊中的程式碼。
}
```
var money=prompt("要提多少錢?","")
if(money>30000){
alert("不能提那麼多錢");
}else{
alert("恭喜,錢給你了");
}
```
if (判斷一){
先做第一次判斷,若正確(true),執行此區塊程式碼。
若第一次判斷錯誤(false),繼續進行下方else if的第二次判斷。
}else if(判斷二){
同上
}else{
若以上所有判斷都錯誤(false),則執行else區塊中的程式碼。
}
```
var n=prompt("請輸入數字","");
if(n>500){
alert(n+">500");
}else if (n>300){
alert(n+">300");
}else
alert(n+"<=300");
}
```
### 一個完整的範例
```Example
var n1=prompt("請輸入第一個數字");
var n2=prompt("請輸入第二個數字");
n1=Number(n1);
n2=Number(n2);
var op=prompt("請輸入運算:+, -, *, /","");
var result;
if (op="+"){
result=n1+n2;
}else if (op="-"){
result=n1-n2;
}else if (op="*"){
result=n1*n2;
}else if (op="/"){
result=n1/n2;
}else{
result="不合法的運算式";
}
```
## 樣板面板值(template literal)
樣板面板值是透過 **反引號** 所包覆,並由 **{}** 和 **$** 所組成
### 支援多行字串
```Example
var a =
`It's not fair.
Why you could use it?
I hate you!!`
console.log(a);
```

### 允許將變數嵌入字串
透過 **$** 和 **{}** 就可以做到
```Example
var age = 30;
var str = 'I am a '+ age + ' year-old engineer.';
console.log(str);
```

```Example
var age = 30;
var str = `I am a ${age} year-old engineer`;
console.log(str);
```

## 轉義
如何區分文字資料與程式本身是個問題,為了解決這個問題,我們需要一個轉義的方式,例如
```javascript=
const dialog1 = "He looked up and said \"don't do that!\" to Max.";
const dialog2 = 'He looked up and said "don\'t do that!" to Max.';
// 有時候需要反斜線出現在文字中時,也可以轉義自己
const s = "In Javascript, use \\ as an escape character in strings."
```
## 特殊字元
反斜線不是只能用來轉義引號,也可以用來表示非列印字元
| 代碼 | 說明 |
|-------|:-----:|
| \n | 換行 |
| \r | 歸位字元 |
| \t | Tab |
| \' | 單引號 |
| \" | 雙引號 |
| \$ | 錢字號 |
| \\ | 反斜線 |
## 數字當字串
把數字放在引號內,就不是數字,而是字串
```javascript=
const result = 3+'30' //結果會是330
const result = 3*'30' //結果會是數字90
```