| JS可以在瀏覽器、node.js 運行環境跑
| RMK : 運行環境並不是程式語言,但他能讓js跑在瀏覽器外
如何在瀏覽器上執行JS


- RMK : 程式碼少時會在瀏覽器上debug,通常還是會在node.js上修改
console.log

- RMK : 會把想要的東西印在terminal
一、基本運算
- 算數運算 
  
- 邏輯運算 
  
- js邏輯短路性質
 - or: 如果前面是True,不管後面是True 或False,後面的都沒有作用。先跑到True,就回傳True的值
 - and: 要全部跑完才能判別是否為True,若為True會回傳最後的值。若前面已出現False,後面的值都沒有作用,直接回傳False
  
- RMK(1) : 數字也可以做邏輯運算
- RMK(2) : Fasle的東西,如 : False、0、" "
二、位元運算
Recall:進位
(1) 十進位(Decimal):碰到10就要進位,數字裡不會有十,9的下一個會是10
- 如 : 1,2,3,4,5,6,7,8,9,10 (一零的一就是進位的意思),11,12,13...
- 數學說明 : 以10為基底,188 =1*10^2 + 8*10^1 + 8*10^0
(2) 八進位(Octal) : 數字裡不會有八,7的下一個會是10
- 如 : 1,2,3,4,5,6,7,10 (一零的一就是進位的意思),11,12,13,14,15,16,17,20 (二零的二就是進位的意思)
- 數學說明 : 以8為基底,123(Oct)=1*8^2 + 2*8^1 + 3*8^0 = 83(Dec)
(3) 十六進位(Hexadecimal) : 數字裡不會有十六,F(15)的下一個會是10
- 如 : 1,2,3,4,5,6,7,8,9,A(10),B(11),C(12),D(13),E(14),F(15),10 (一零的一就是進位的意思),11,12,13...,1A,1B,1C,...1F,20 (二零的二就是進位的意思)
- 知識點 : 色碼就是十六進位表示法
  
(3) 二進位(Binary) : 數字裡不會有二
- 如 : 0,1,10,11,100,101
- 數學說明 : 以2為基底,1010(Bin)=1*2^3 + 1*2^1 = 10(Dec)
>>  << (位移運算)
- 說明 : 把所有位元往右移X位,往左移X位,電腦位元是以2進位呈現
- 優點 : 電腦運算效能高
  
- RMK : 0100 = 4 << 1000 = 8 ,右移1位相當於乘2^1,可以運用在乘除(2的幾次方)
bitwise operation(位元運算)
- 說明 : and(&) or(|) xor(^) not(~),先將輸入的數值轉成二進位,再對每個位數進行and(&) or(|) xor(^) not(~)運算
- 範例(and)
  
- 範例(or)
  
  
- 運用 : 位元遮罩-判斷奇偶數 
 已知
 (1) 偶+偶=偶,偶+奇=奇
 (2) A & 1 =1,則A的最後一個數值為1;A & 0 = 0,則A的最後一個數值為0
 又因為,二進位中唯一會出現奇數的狀況為- 1*(2^0)=1
 故,A的最後一個數值為1,A為奇數,OW A為偶數 (QED)
- RMK(1) : - & (位元運算)、&&(邏輯運算)
- RMK(2-and) : 1 and 1 是 1、1 and 0 是 0
- RMK(3-xor) : 都一樣就傳 0 ,不一樣就傳 1,讀做exclusive or
三、變數
- 說明(1宣告) : var 為宣告變數,宣告後內部的運作仍會給予型態
- 說明(2加加或減減) : a+=5 等於a=a+5;a++ 等於 a+=1;a-- 等於 a-=1
 加加放前面放後面的差別
  
- 說明(3型態) : 以 - typeof去查看變數的型態- 第一類、 Primitive : boolean、number、string
- 第二類、 object、undefined、function
 
- 說明(4陣列 Array) : - 優點 : 可以用索引的方式取得資料,變數無法以索引的方式取得資料。故陣列通常會存放性質相近的東西
 
- 說明(5物件 Object ) : - var student=[] var peter={ name : 'peter huang', grade : [90,88,77,100], gender : "m", father :{ name : "nick huang" phone: "0909090" } student.push(peter) console.log(student[0].name) console.log(peter['name'])- 優點 : 陣列只能儲存相似的東西,如我想要知道學生的名字、成績、地址,以多個陣列的方式,會非常的不方便。物件就是一個資料結構可以儲存所有的東西,儲存的東西可以是array、object、function...
 
- 說明(6 變數運算留心) : - 型態 : ex 數字 + 字串 = 字串相加
- 浮點數誤差
 
- 說明(7 == 與 ===) : - 差異 : ===判斷相等且型態相同,==判斷相等但不判斷型態。用===除錯會較容易
- RMK : =,表示assign
 
- 說明(8 變數在底層的運作 ) :從object等號真正理解變數 - 答案都是false
  - JS底層比的是記憶體位置 : 可以將obj裡存的東西想成是記憶體位置,他們不相等是因為他們記憶體位置不是指向同一個東西
- 當你想要存一般的資訊(數字、字串等等)的時候,變數裡面存的內容就真的是那個資訊。想存物件或陣列的時候,變數裡面存的內容其實是「指引」。「指引」兩個字,其實可以直接代換成「指標」,對,就是 C 語言裡面那個指標。一般的變數存資訊,而指標存的是記憶體。課程文章 : 從博物館寄物櫃理解變數儲存模型 
  
- 範例、如果給他一個新的物件,他會指向新的物件的位置 
  
  
  
 
- RMK(1) : "undefined"已宣告,但沒有給值,"not defined"尚未宣告變數,"unexpedcted number"變數不能以數字開頭
四、條件判斷
- 兩個以上的條件請用 && 與 ||
(1) 說明 : 由左至右執行條件,70>=score=65 會先回傳true,因true >= 60 (並未符合條件),故不會回傳pass
var score=65 
if(70>=score>=60){ 
console.log("pass");}
- 條件(if else) : 
 (1) 說明 : 提供下列更簡潔方式- if(){ } if else(){ } else{ }- (2) RMK (可讀性) : - var score=60 var isPass=score>=60
- 多條件(switch case) : 
 (1) 說明 : 有些題目可以依陣列方式對應,會更簡潔
    //法一
    var month=3
    var month_to_chinese=['1月','二月','三月','四月']
    console.log(month_to_chinese[month-1])
    // 法二
    var month =1
    switch case(month){
        case 1 :
        case 4 :
            console.log("一月")
            break
        case 2 :
            console.log("二月")
            break
        case 3 :
            console.log("三月")
            break
        default:
            console.log("hey")
            break
    }
- 三元運算子(ternary) :
 condition ? A : B如果是 true 回傳 A,如果是 false 回傳 B
 (1) 說明 : 在只有兩種狀況下,可簡化程式碼,且不損可讀性
var score=75
var message>=60 ? 'pass' : 'fail'
五、迴圈
| 不確定迴圈怎麼跑 : 一行一行寫下迴圈跑完的結果,可以在網頁上debug
- 前身(goto) : js無,其他語言有var i =1 label: console.log(i) i++ if(i<=100){ goto label; } console.log("end")
- 先做再說(do while) :while(true) 就會繼續執行block中的內容
var i =1 //(1)初始值
do{
  console.log(i)
  i++ //(3)i每一圈迴圈要做的事
}while(i<=100) //法一、指定終止條件 //(2)終止條件
console.log("i=",i) // i=101 跳出迴圈
var i =1
do{
  console.log(i)
  i++
  if(i>100){
    break // 指定條件,跳出無窮迴圈
  }
}while(true) //法二、無窮迴圈
console.log("i=",i) // i=101 跳出迴圈
- continue : 會直接跑到下一圈,忽略下面的code
var i=1
do{ 
  if(i%2===1){
     continue
  }
  console.log(i)
  i++
}while(i<=100)
console.log("i=",i)
// 出現無窮迴圈
i=> 1
do 
(1%2===1) =>true 
continue
while(i<=100) =>true
do
(1%2===1) =>true 
continue
while(i<=100) =>true
... 又跑回圈do裡
- 先判斷條件再說(while) :
 while(i<=100){
    console.log(i++) //會先log i 再執行 i+1,所以印出 1 2 3 ... 100
}
- (for loop) :
 | 怎麼檢查這個東西是否正確,最好用的方式去改他,看他的輸出跟你想的是否一樣
// ;表示這行結束
//for(初始值;終止條件;i每圈要做的事情){}
for(var i=1;i<=100;i+=2){
    console.log(i);
}
// for-loop結合 array
var scores=[10,20,40]
var sum=0;
for(var i=0;i<scores.length;i++){
    sum+=scores[i];
}
console.log(sum);
六、函式(function) :不知道怎麼解題,可以先從寫下 function 開始
呼叫 function時要確認,它到底是改變原本的值,還是回傳一個新的值,還是兩個都有,如果不清楚要查清楚,不然會出現一堆bug
function可以分兩類,一類是你運算完需要他回傳甚麼(要知道結果)、一類是僅呼叫他(不用知道結果)
Recall : 國中數學
y=f(a,b,c) =2a+b+c where a,b,c is parameter , f() is called function and 2a+b+c is return value
- (function ) 語法 : 注意 return 後面要接東西,不然會解讀成兩句變成沒有意義的東西undefined,return { 後面緊跟大括號
// 變數的命名會影響可讀性
function generateArray(from ,to ){ 
    var result = []
    for(var i = from ; i <= to ;i++){
        result.push(i)
    }
    return result  // 如果不回傳值會變成undefined
}
console.log(generateArray(3,10))
// 也可以用 a=3 b=10 然後 console.log(generateArray(a, b))表示
// 卡關時可以先寫成 function 形式 : 好處是可以先把大綱寫出來,把不會的地方抽出來,最後再以填空的方式完成不會的部分。 
function logEven(number){
    if (number%2===0){
        console.log(number)
    }
}
function print1to100(){
    for(var i=1;i<=100;i++){
     logEven(i)
    }
}
print1to100()
- 宣告 function 的不同方式 :
//法一 using funtion 
function hello(){
    console.log("hello")
}
hello()
//法二 using varibale to declare function
 var hello =function(){
    console.log('hello')
 }
 hello()
- 匿名函式 (anonymous function) :
 優點 : 直接更動匿名函式,不用更改很多東西
function transform(arr,transformFunction){
  var result =[]
   for(var i=0;i<arr.length;i++){
      result.push(transformFunction(arr[i]));
   }
   return result
}
console.log(
   transform([4,6,7],function(x){
     return x*10  //可以將整個function丟進來,不用幫他取名
   })
   )
- function 中的參數可以是 function :
//transform  [1,2,3] =>[4,5,6]
function transform(arr,transformFunction){
   var result=[]
   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) // 可以將參數換成任何我想要的function進去
)
- 名詞解釋 (參數、引數) :
(1) 參數(parameter) :
(2) 引數(argument) : 真正傳入function的東西
//  js特有 可以看傳入的引數是什麼 ,可以藉由 argument 看到底傳了甚麼東西進來
function add(a,b){
   console.log(arguments)
   return arguments[0]+arguments[1];
}
console.log(add(2,5))
/* $ node index.js (回傳result)
[Arguments] { '0': 2, '1': 5 }  arguments is object
7
*/
- 使用function的注意事項 (pass by value) : obj. 可能會影響到外面的東西
function swap(a,b){
   var temp=a;
   a =b;    // a b 是賦值來的,他的記憶體位置與number1、number2無關
   b =temp;
   console.log(a,b) // => 20,10
} 
var number1=10
var number2=20
console.log(number1,number2) // 10,20
swap(number1, number2)
console.log(number1,number2) // 10, 20
- 使用return的注意事項 :
function addValue(obj){
  // 因為 obj=a 
   obj.number++ // 他們指向同一個東西,所以改動也會影響外面的值
   return 1
}
var a ={
   number: 10
}
addValue(a)
console.log(a)
function addValue(obj){
  // obj=a
   obj={
      number :200 // 給他一個新的物件,他會指向新的位置,但不會改到原本的
   }
   return 1
}
var a ={
   number: 10
}
addValue(a)
console.log(a)
// (1) 不需要知道結果
function sayHi(name){
   //console.log("Hi",name)
}
var a = sayHi("nick") //宣告一個變數 a 去接受 function 的回傳值
console.log(a) // return undefined
// function 不加 return 會預設為 undefined,加不加 return 沒差
// (2) 需要知道結果
function double(x){
   console.log(1234567)
   return x*2 //需要回傳值,如果不寫 return 會回傳預設值 undefined
   console.log("apple") //一用 return 就會跳回前,下面的程式碼都不會執行
}
var  result=double(4)
console.log(result)
- 使用 main (aim at reading elegant) :
function double(x){
   return x*2
}
function main(){
   var result =double(3)
   console.log(result)
}
main()
七、其他 :
(一)、除錯絕招 : console.log
說明 : 在每一行、所有不知道在幹嘛的地方加上console.log
function isPrime(num){
   console.log("num",num)
   if(num===1){ return false;}
   if(num===2){return true;}
   for(var i=2;i<num;i++){
      console.log("i=",i)
      if(num%2===0){
         console.log("num % i===0",num , i)
         return false;
      }
      else {
         console.log("else",num , i)
         return true;
      }
   }
}
console.log(isPrime(15)) // return true but 15 is not prime
/*$ node index.js
num 15
i= 2
else 15 2
true
 * hence, return true should outside the loop/
(二)、difference between return and console.log
| 回傳與印出的差異
說明 : 回傳完之後他會給你值,但是不會印出東西,要印出東西要用 console.log。
RMK (1) : 一般是對 function 回傳值做測試,而非 console.log 的值
RMK (2) : 呼叫 function 是希望給出回傳值
function add(a,b){
   console.log(a,b) 
   //預設 return undefined
}
console.log(add(1,2)) //先執行add(1,2) => log 出 (a,b) 接著return undefined=> 變成 console.log(undefined)
/*
$ node index.js
1 2
undefined
*/
function add(a,b){
   return a+b
}
add(1,2) //因為沒有log 所以回傳完後印出任何東西
// 要印出的話=> console.log(add(1,2))
/*
$ node index.js
*/
ps. 與網頁不同,node 不會印出回傳值

(三)、不可變 immutable
當你對 array或object 做 method時,要注意它可能會改動到原本的東西。如果她回傳的東西不是 array 或 object ,你就不需要用一個變數去接。 對於字串、數字來說,它永遠是 immutable,所以需要以變數去接。
| mdn said : all types except objects define immutable values
(不會改變原本的值,只能藉由新建一個記憶體空間回傳一個新的值)
(array 也是物件的一種)
var a = "hello"
a =  "yo"
a : "hello" 0x01
a : "yo" 0x02
var a = "hello"
 a.toUpperCase() //它會回傳一個新的東西,但因為沒有接收,所以甚麼事情都不會發生,不會變成 HELLO
console.log(a) // 回傳hello 理由是immutable,它無法改變a的值
// 所以改變,要回傳一個新的值的情況會改成下列寫法
// a = a.toUpperCase()
var a = "hello"
function change(str){
   str ="123";
}
change(a)
console.log(a) //回傳"hello"
- array 說明 :
var arr=[1,2,3]
arr=arr.push(4)
/*  arr = arr.push(4) 兩步驟拆解 
    step1.[1,2,3] 00x0 => [1,2,3,4] 00x0 
   step2. arr.push() this function retun the new length of the array
   所以正確的寫法是 arr.push(4)
   */
console.log(arr)
- splice(會改動到原本的array)、slice(不會改動到原本的array)

![DEC 14 2023 PROCL-5: User does not have permission to perform a local registry operation on this key. Authentication error [User [root] [已解決]](https://static.coderbridge.com/images/covers/default-post-cover-2.jpg)
