### 邏輯運算: and or not
`&&`: 兩者為true才會true
```
true && true ->true
true && false ->false
false && true ->false
false && false ->false
```
`||`: 其中一個為true就會true
```
true || true ->true
true || false ->true
false || true ->true
false || false ->false
```
`!`:反向
```
!true ->false
!false ->true
```
### 邏輯運算的小撇步:|| 與 && 的短路性質
`||`:第一個是true,就直接印出;如果第一個是false就印出第二個
```
3 || 10 -> 3
false || 5 -> 5
```
`&&`:要兩個都是true才會回傳,所以第一個如果是true那決定權在第二個身上,回傳的值也是第二個的;如第一個是false那就直接回傳第一個值
```
3 && 10 -> 10
true && false -> false
0 && 10 -> 0
```
falsy(假值): undefined 、 null 、 NaN 、 0 、 "" (空字串)和 false
### 變數宣告與 undefined
variable變數:像是裝東西的箱子
#### 命名規範
- 名字不能數字開頭、特殊符號
- 不能使用保留字(var this等)
- 可用underscore下底線連接: 例如:this_is_box
- 駝峰式命名:例如:thisIsBox(推薦)
==記得命名方式要統一==
undefined: 意思是有宣告但是沒有賦予值
### 可以 ++ 嗎
```
a = a + 5
=>a += 5(縮寫)
b = b - 5
=> b -= 5(縮寫)
a = a + 1
=> a++ (縮寫)
a = a - 1
=> a-- (縮寫)
```
#### `++a`與`a++`差別
`a++`會等那行程式跑完才執行`a++`,例如
```javascript!
var a = 0;
console.log(a++ && 30);
```
這行程式碼執行順序可以看成:
```javascript
console.log(a && 30); //0
a++;
```
`++a`則是先執行`++a`,再執行那行程式碼
```javascript!
var a = 0;
console.log(++a && 30);
```
這行程式碼執行順序可以看成:
```javascript!
++a;
console.log(++a && 30); //30
```
### 從 Object 的等號真正的理解變數
```javascript
console.log([] === []);
console.log([1] === [1]);
console.log({} === {});
console.log({ a: 1 } === { a: 1 });
//結果皆為false
```
為什麼全部都是false?
因為要注意,Object他是傳參考,也就是參考記憶體的位置,所以第一個物件的記憶體位置可能為0x01,第二個物件的記憶體位置為0x02,指向都不是同一個物件,所以為false。
例如:小明的Mac和小白的Mac,同樣都是Mac,長的都一樣,但是是不同人的

```javascript!
//範例
var obj = {
a: 1
}
//宣告obj2等於obj,並修改a值
var obj2 = obj;
obj2.a = 5;
console.log(obj === obj2); //true
```
obj2修改記憶體位置0x01的a值,`obj === obj2` 仍為true
使用console.log確認obj和obj2
```javascript!
console.log(obj); //{a:2}
console.log(obj2); //{a:2}
```
obj的a值也變成2,這是因為obj和obj2指向同一個記憶體,當obj2修改a值,其實也等於obj的a值修改
如宣告obj2等於另一個物件,例如`obj2={b:1}`,這時{b:1}為新的記憶體位置0x02,此時obj就不等於obj2
```javascript!
var obj = {
a: 1
}
var obj2 = obj;
var obj2 = {
b: 1
}
console.log(obj); //{a:1}
console.log(obj2); //{b:1}
console.log(obj === obj2); //false
```
### if/else
if後面的括號是放條件判斷,例如:true/false、比較運算
兩個以上的條件用`&&`或是`||`連接
else 和第二組大括號並不是必要的
[MDN:if/else](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)
```javascript1=
//語法
if (condition){
statement1(code to run if condition is true)
}
// With an else clause
if (condition){
statement1
} else {
statement2
}
```
condition:表達式的值為真值(truthy)或假值(falsy)
範例:
```javascript=
if (true) {
console.log("pass");
}
```
```javascript=
if (10 > 5) {
console.log("pass");
}
```
```javascript=
var score = 75;
if (score >= 70 && score <= 80) {
console.log("pass");
}
```
```javascript=
var number = 11;
if (number % 5 === 0) {
console.log("是5的倍數");
} else {
console.log("不是5的倍數");
}
//number % 5 === 0 結果false
//!(number % 5) 結果為!1,也就是0,為false
//兩者寫法都可以
//結果印出"不是5的倍數"
```
### if/else if
else if 可以多個
條件成立了就會執行該行程式碼,後面的就不會執行
```javascript=
var age = 18;
if (age >= 65) {
console.log("old");
} else if (age >= 40) {
console.log("壯年");
} else if (age >= 20) {
console.log("young");
} else {
console.log("children");
}
```
### switch case
用於多個條件判斷
```javascript!
var month = 1;
switch (month) {
case 1:
console.log("1月")
break
case 2:
console.log("2月")
break
case 3:
console.log("3月")
break
default:
console.log("無此月份")
}
```
break:是要讓他執行中斷,如沒寫break,條件成立時case 1、case 2、case 3、default會全部印出
default:是當以上沒有條件成立會跳到default
### 三元運算子(Ternary)
建議只放一層時使用,不建議巢狀,會不好閱讀
> condition ? exprIfTrue : exprIfFalse
> 意思是條件成立回傳exprIfTrue,條件不成立回傳exprIfFalse
[MDN:ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_operator)
```javascript!
var score = 50;
var message ='';
//原本寫的判斷式
if (score >= 60){
message = 'pass';
} else {
message = 'fail';
}
console.log(message);
```
```javascript!
//修改成三元運算
var score = 50;
var message = (score >= 60)?'pass':'fail';
console.log(message);
```
### 迴圈
重複做一樣的事情
無窮迴圈:中止條件有錯,所以不會中止
一開始不懂程式執行哪一行就自己寫下來
#### do/while
有break、continue可以使用
```javascript1!
//do/while範例
var i = 1; //初始值
do {
console.log(i);
i++;
} while (i<10)
console.log('i=',i);
```
#### while
有break、continue可以使用
```javascript!
//while範例
var i = 1; //初始值
while (i<10) { //中止條件
console.log(i);//i每圈要做的事情
i++;
}
console.log('i=',i);
```
#### for loop
把初始值,條件,每圈要做的事情寫成一行
```javascript!
var score = [50,80,65,90,75];
var sum = 0;
for (var key = 0 ; key < score.length; key++){
// console.log(score[key]);
sum += score[key];
}
console.log(sum); //360
```
### 函式(Function)
參數名可自定義,例如min、max、n等
要有return 才能把值傳出去
```javascript!
function abc (min,max){
return min*2+max*5
}
console.log(abc(4,3));
```
#### 宣告函式
```javascript!
//方式1
function hello(){
console.log("hello!");
}
//方式2 宣告一個變數為function
var hello = function(){
console.log("hello");
}
```
function的參數可以是數字、字串,也可以是function,陣列,物件等
```javascript!
function transform(arr,transformFunction){
var result = [];
//先遍歷完,再透過double函式把陣列值都乘於2
for(var i = 0; i < arr.length;i++){
result.push(transformFunction(arr[i]));
}
return result
}
function double(x){
return x*2
}
console.log(transform([1,2,3],double)); //[2,4,6]
```
參數(Parameter)和 引數(Argument)
```javascript!
function add(a,b) {
return a+b
}
add(3,5);
```
以上面範例來看
a,b是參數(Parameter)
3,5是引數(Argument)
JS在function裡面提供查引數(Argument)
```javascript!
function add() {
console.log(arguments);//{"0": 3,"1": 5}
//也可以這樣寫(較少使用)
return arguments[0]+arguments[1]
}
add(3,5); //8
```
argument補充
類陣列:長得很像陣列的物件
[MDN:arguments](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments)
==(還看不明白)==
[影片: 使用 function 時的注意事項 ](https://lidemy.com/courses/js101-javascript/lectures/6081026)
[文章: 深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?](https://blog.techbridge.cc/2018/06/23/javascript-call-by-value-or-reference/)
function如果沒有寫return,預設回傳值是<font color=#800000>`undefined`</font>
一旦return了,return後面的程式碼就不會執行
```javascript!
//有return
function double(x){
return x * 2
console.log("a");//不會執行
}
var result = double(7);
console.log(result); //14,return值存在result變數
```
```javascript
//沒有return
function double(x){
//return x * 2
}
var result = double(7);
console.log(result); //undefined
```
### Number 類型的內建函式
字串轉數字方法,詳見MDN的[Number](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Number)、[Math](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math)
* parseInt(),Int為integer整數
* parseFloat(),取浮點數
* toFixed(),取小數到第幾位數
```javascript!
var a = 10;
var b = "20.44875";
console.log(a + b);//1020
console.log(a + parseInt(b,10));//30,取10進位整數
console.log(a + parseFloat(b).toFixed(2));//1020.45,浮點數取2位
console.log(Number(b).toFixed(3));//20.449,取浮點數3位
```
* [Number.MAX_VALUE](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE):在JS可以存的最大數值
* Math.ceil():無條件進位
* Math.floor():無條件捨去
* Math.round():四捨五入
* Math.random():隨機數0~1(有包含0,不含1)
```javascript!
console.log(Math.ceil(11.35)); //12
console.log(Math.floor(11.35)); //11
console.log(Math.round(11.35)); //11
console.log(Math.floor(Math.random()*10 + 1)); //取1~10的隨機數
//因為random是取0~0.999999....的數(先抓6位數),所以先乘於10變成0~9.999999,最後加1變成1~10.99999,再使用floor無條件捨去取得1~10的隨機數
```
### String 類型的內建函式
* String.prototype.toUpperCase():英文字轉大寫
```javascript!
let str = "abc".toUpperCase();
console.log(str); //ABC
```
* String.prototype.toLowerCase():英文字轉小寫
```javascript!
let str2 = "AAA".toLowerCase();
console.log(str2); //aaa
```
* [String.prototype.charCodeAt()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt): ASCII code每個字都有對應數字,使用charCodeAt可以得到字的號碼是多少
以下範例可以發現,大寫A和小寫a相差32
```javascript!
let a = "A";
let aCode = a.charCodeAt(0); //取字串中第幾個,跟陣列一樣從0開始
console.log(aCode);//表示A的代號65
let aa = "a";
let aaCode = aa.charCodeAt(0);
console.log(aaCode);//表示a的代號97
```
* [String.fromCharCode()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode):跟charCodeAt相反,可以把代碼轉成對應的字
```javascript!
let str4 = String.fromCharCode(66);
console.log(str4); //"B",表示代碼66為大寫B
```
* [String.prototype.indexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf):取索引值
```javascript1!
let str5 = "hi peter be the light";
let str5Index = str5.indexOf("peter");//會抓取這個單字的第一個字母的index
console.log(str5Index);//3
```
* [String.prototype.replace()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace):取代字
```javascript!
let str6 = "david in the bible".replace("d","?");//把d取代為問號?,只會取代第一個d
console.log(str6); //"?avid in the bible"
//取代多個
let str7 = "david in the bible".replace(/d/g,"?");//把所有d取代為問號?
console.log(str7); //"?avi? in the bible"
```
* [String.prototype.split()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split):設定把字切開變成陣列
```javascript!
//split字串切開成陣列
let str8 = "the truth and helps people understand the world.".split(" ");//設定用空白為切割依據
console.log(str8); //["the","truth","and","helps","people","understand","the","world."]
console.log(str8[4]); //"people"
```
* [String.prototype.trim()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim):前後空格清除
```javascript!
//trim清除前後空格
let str9 = " hello world";
console.log(str9.trim()); //"hello world"
```
* [String.prototype.trim()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim):前後空格清除
```javascript!
//trim清除前後空格
let str9 = " hello world ";
console.log(str9.trim()); //"hello world"
```
* [String: length](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length):字串長度
字串可以像陣列用索引值存取
```javascript!
let str10 = "top the world";
console.log(str10.length);//13
console.log(str10[0]);//t
for (let i = 0;i < str10.length; i++){
console.log(str10[i]);//可以把每個字母一一取出
}
```
### Array 類型的內建函式
* [Array.prototype.join()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join):用某個字元把陣列內容接在一起
```javascript!
let arr = [11,22,33];
console.log(arr.join("!"));//"11!22!33"
console.log(arr.join(" "));//"11 22 33"
```
* [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map):建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合
```javascript!
let array1 = [1,2,3,4,5];
let newArray1 = array1.map(function(item){
return item*2
})
console.log(newArray1); //[2,4,6,8,10]
```
* [Array.prototype.filter()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/filter):篩選
1. 會回傳新陣列
2. 原陣列不會被修改
```javascript!
let arr = [2,7,16,50,77,100];
let newArr = arr.filter(function(i){
return i>20
})
console.log(newArr);//[50,77,100]
```
* [Array.prototype.slice()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
1. 會回傳新陣列
2. 原陣列不會被修改
3. begin,end可使用負數索引
> 語法: arr.slice([begin[, end]])
> Zero-based index at which to end extraction, converted to an integer. slice() extracts up to but not including end.
> 意思是slice 提取不會包含到索引end
```javascript!
let drink = ["tea","coffee","soda","milk","water"];
let newDrink = drink.slice(1);//["coffee","soda","milk","water"]
let a = drink.slice(3,5);//["milk","water"]
let b = drink.slice(2,-2);//["soda"]
```
* [Array.prototype.splice()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
1. 原陣列會改變
2. 可新增元素,也可刪除元素到陣列中,能同時執行
>語法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
>start:起始索引值
>deleteCount:要刪除的元素數量,若沒寫值,則start開始到最後一個元素都會被刪除
>item1,item2:要新增的元素
```javascript!
let people = ["小黑","小白","小明","小花"];
let a = people.splice(1);//表示從索引值1開始,刪除所有元素 =>["小白","小明","小花"]
console.log(people);//people陣列現在為["小黑"]
```
```javascript!
let fruit = ["apple","banana","grape","peach"];
let b = fruit.splice(2,1,"bb");//表示從索引值2開始,刪除1個元素,並插入"bb" =>["grape"]
console.log(fruit);//["apple","banana","bb","peach"]
```
* [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort):排序
1. 對原陣列的所有元素進行排序,回傳排序後的陣列,是修改原陣列
2. 預設的排序順序是根據字串的 Unicode 編碼位置
> sort()
> sort(compareFn)
> compareFn:
> 1.如省略參數,陣列裡的元素會被轉為字串,並依據每個字元的Unicode code排序
> 2.此函數會決定元素的排序,函數裡的參數,第一個為a,第二個為b

```javascript!
//omitted
let color = ["red","green","blue","orange","white"];
console.log(color.sort()); //["blue","green","orange","red","white"]
let num = [1,3,7,50,33];
let newNum = num.sort((a,b) => a - b); //升冪
console.log(newNum); //[1,3,7,33,50]
```
* [Array.prototype.indexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf):找陣列索引值
```javascript!
let arr = ["apple","orange","peach","durian"];
let newArr = arr.indexOf("durian");
console.log(newArr); //durian的索引值是3
```