筆記、[JS101] 語法


Posted by s103071049 on 2021-04-20

| 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)

    c
  • 運用 : 位元遮罩-判斷奇偶數
    已知
    (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 是 11 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)

#JS 語法與常犯錯誤







Related Posts

[ 紀錄 ] 實戰練習 - 部落格 (以 php 實作前端 + 後端)

[ 紀錄 ] 實戰練習 - 部落格 (以 php 實作前端 + 後端)

給自己看的 JS 進階-變數

給自己看的 JS 進階-變數

Day07 Life Cycle

Day07 Life Cycle


Comments