我的第一堂 - JavaScript 02 變數, 判斷式


Posted by krebikshaw on 2020-06-16

前言

這篇文章會提到的內容如下:

  • JavaScript 的變數
  • 變數的類型
  • 不同型態下變數運算的陷阱
  • 物件的儲存方式
  • JavaScript 的判斷式

JavaScript 的變數

變數 我們可以把它比喻成 箱子,我們給這個箱子一個名稱,並放東西進去。

  • 比如說我有一個叫做 文具 的箱子,我在裡面放一隻 鉛筆
    • 那除非我把裡面的 鉛筆 拿走或換掉,否則我所我講的 文具 指的就是裡面的鉛筆。

注意:每個變數在第一次使用時都要先 宣告,目的是告訴電腦,這個東西是什麼。

宣告的方式:

  var 文具 = 鉛筆

var 就是告訴電腦這是一個 變數(variable)

= 在這個地方不是我們數學上認識的 等於,它指的是把右邊的值,賦值到左邊的變數上面(也就是把鉛筆放入叫做文具的箱子裡)。

  • 那如果你問我,數學的 等於 要怎麼表示?我先跟你說可以用 ==,文章後面會說明。
var 文具 = 鉛筆
console.log(文具)

結果: 鉛筆

console.log() 是叫電腦把東西印在畫面上的指令,所以在這個地方就是叫電腦把文具這個變數印在螢幕上。 最後印出的值是 鉛筆

變數的取名
實際上我們在寫程式的時候,我們不會取中文名字,我們會用英文跟符號來表示。

  • 變數的命名是非常重要的,要取的讓自己跟別人能看得懂。

    • 你可以一看名稱就知到它代表的意思是什麼,在閱讀時才不用花太多時間
      var people_count
      var peopleCount
      
  • 這兩種方式都可以看的出,這個變數想表達的是,人數 的概念。

    • 上面是用 _ 將兩個單字隔開
    • 下面是用單字第一個字母寫成 大寫 來表示。(這種表示方式叫做 駝峰式)

參考資料:

資料型態

JavaScript 有 7 種資料型態 ( 6 種原始型態 + 1 種物件型態)

  • Primitive type 原始型態
    1. null : 空值
    2. undefined : 有宣告變數,但是沒有值
    3. string : 字串
    4. number : 數字
    5. boolean : true, false
    6. symbol (ES6) : ES6 新增的型態,暫不討論
  • Object 物件型態
    1. object (array, function, date ......)

console.log(Object.prototype.toString.call(待測值)) 可準確得到資料型態

  • 補充 1: Primitive type 有不可變特性

    • ex. var str = "hello"
      var newStr = str.upperCase()
      只能回傳新的數值,不可改變 str 的值
  • 補充 2:null 明明是原始型態,但是用 typeof null 查看會回傳 object

    • 這是 JS 廣為人知的 bug,因為一但修正了會影響太多層面,所以才決定不做修正了。
  • 補充 3:可以用 Array.isArray() 來檢測是否是 array

陣列 & 物件

陣列 可以用來存放同類型的資料,

  • 有點像是郵箱

我的 郵箱 陣列,放的都是信件,我的郵箱可以很多個,也可以 0 個。我可以任意的決定我要把信件放進哪一個郵箱,或任意的打開我想查看的郵箱。

var 郵箱 = [小明的信, 小花的信, 空的, 空的, 空的, 小白的信]
郵箱[0] = 小明的信 // 第一個郵箱裡放的是小明的信
郵箱[1] = 小花的信
郵箱[2] = 空的
郵箱[3] = 空的
郵箱[4] = 小白的信

陣列的表示方式就是用 [ ] 把東西包起來,然後把裡面的東西用 , 號隔開。
郵箱[0] 代表我要撈取裡面第1個資料

  • 你說我寫錯了吧!第一個資料怎麼會寫 0
    • 在程式語言裡,很多時候第一個資料都會是 編號 0
    • 所以第二筆資料的編號就是 1,以此類推。

物件keyvalue 組合的一種存放資料形式。

  • 組合的形式是 key: value ,
    • 如果我把 key 設成 name,value 設成 長頸鹿,就可以寫成下面這樣:
var 自我介紹 = {
    name : 長頸鹿 ,
    age : 15 歲 ,
    phone : 0800 - 092 - 000
}

這就是一個物件的寫法,用 { } 包起來,裡面寫上 key 跟 value 並且用 , 來隔開。

我要如何取得物件的值呢? 使用 <物件名稱>.<key 的名稱>

自我介紹.name = 長頸鹿
自我介紹.age = 15 歲
自我介紹.phone = 0800 - 092 - 000

來看看實際的例子

var changekey = cat
var oProfile = {
    name : "長頸鹿" ,
    cat : "皇阿瑪" ,
    oFather : {
        name : "樹懶" ,
        cat : "豆漿"
    }
}

console.log( oProfile.cat );  // 皇阿瑪
console.log( oProfile["cat"] );  // 皇阿瑪
console.log( oProfile[changekey] ); // 皇阿瑪
console.log( oProfile.oFather.cat ); // 豆漿

參考資料:
你懂 JavaScript 嗎?#17 物件(Object)

變數運算的陷阱

變數運算有許多需要注意的地方

  • 比如說 a = a + 1 是什麼意思?

    • 還記得上面說到的 = 是指 賦值 的意思嗎?
    • 所以這段的意思就是把右邊的 a+1 賦值到左邊的 a
    var a = 0
    a = a + 1   //  右邊的 a + 1 就是 0 + 1 賦值到左邊後
                    a 就會等於 1
    
  • 像這樣 自己 = 自己 ( + or - ) 數字 可以用一種縮寫方式:

    a = a + 5
    a += 5        // 這兩行的意思是一模一樣的
    
    a = a - 3
    a -= 3        // 這兩行的意思也一模一樣
    
  • 由於 +1-1 這兩個動作太長需要使用了,於是就特別給他個方便的指令: ++--

    a = a + 1 
    a += 1 
    a ++          // 這三行指令的意思是一模一樣的
    
    a = a - 1
    a -= 1
    a --          // 這三行指令意思也一模一樣
    

需要小心的地方
若是在 = 後面直接寫上 數字,這樣變數的型態就會是 number
若是在 = 後面把 數字" 包起來,變數型態會是 string

var a = 3    // 這邊的 a 是個 數字 number 
var b = "3"  // 這邊的 b 是個 字串 string
  • 所以我們在運算的時候,不能夠這樣子寫 3 + "3",這樣會變成 數字 + 字串,結果不是我們想要的。
var a = 3
var b = "3"
console.log( a + b )    // 會得到 "33"

數字字串 相加,程式會自動判定為 字串 相加,所以會得到 33

  • 所以我們在設定變數的時候,不能夠設定錯誤,該是 數字 就是 數字,該是 字串 就是 字串,才不會發生意想不到的結果。

注意浮點數
由於 JavaScript 在儲存 小數 的時候,不會那麼精準,會帶一點誤差
(跟儲存方式有關係),所以我們在用小數做計算時,要注意這些誤差所造成的錯誤。

== v.s ===

==:在 == 比較式中,JavaScript 會先幫兩邊不同的變數類型、先進行類型轉換、再進行比較。

  3 == "3"   // 會回傳 true,因為 JaveScript 會幫你先把變數類型轉換好
  "1" == true   // 也會回傳 true

===:嚴格進行比較,數值與變數類型都要相同。

  3 === "3"   //  會回傳 false
  "3" === "3"  //  會回傳 true
  3 === 3     //  會回傳 true
  • 為了避免變數類型的疑慮,在寫程式時,建議使用嚴謹一點的 === 判斷相等。

從物件了解變數

記憶體位置
假設有兩個物件 obj1, obj2 我們放入一樣的東西之後做比較:

var obj1 = { a : 1 };
var obj2 = { a : 1 };

console.log( obj1 === obj2 )   // 會回傳 false
  • 兩個物件放入一模一樣的東西,相比結果卻是 false。

這個不是 bug 讓我們慢慢解釋

  • 因為 JavaScript 在 物件 的比較,是比較 記憶體位置
    1. 第一個 obj1 會在電腦裡 新增 一個記憶體位置,假設是 01x01,裡面存放著 {a: 1}
    2. 第二個 obj2 會在電腦裡 再新增 一個新的記憶體位置,假設是 01x05,裡面存放著 {a: 1}
    3. 而 obj === obj2 比較的其實是 0x01 === 0x05,所以當然會回傳 false 啦!

兩個物件 obj1, obj2 但這次我們把第二個物件 obj2 指向第一個:

var obj1 = { a : 1 };
var obj2 = obj1

接著在更改 obj2 的值,看看會發生什麼事

obj2.a = 2;
console.log( obj1 )   // 結果是 2
console.log( obj1 === obj2 )   //  結果是 true ,相同記憶體位置
  • 當我們把 obj2 指向 obj1 的時候,會把 obj2 指向跟 obj1 一樣的記憶體位置。
  • 因為兩個物件是指向同個記憶體位置,所以改動其中一個物件的值,另一個物件的內容也會改變。

但若是我將 obj2 指向 obj1 後,又 賦值 一個新的內容進去

var obj1 = { a: 1 };
var obj2 = obj1;
console.log( obj2 === obj1 )  //  true  此時指向同個記憶體位置

obj2 = { b: 1 );              //  賦值新的內容進去
console.log( obj2 === obj1 )  //  false  此時指向的記憶體位置就不同了
  • 當 obj2 被傳入新的內容,就會給 obj2 一個新的記憶體位置,所以兩個物件的連結就斷開了。

JavaScript 的判斷式

如果今晚有空,我們一起去看電影,沒空的話就下次再約

  • 這就是很標準的判斷式,判斷條件成立的話要做什麼,條件不成立要做什麼
  • 換成 JavaScript 語法:
    if ( 今晚有空 ) { 一起看電影 } 
    else { 下次再約 }
    
  • if 中括號 ( ) 裡面的條件成立,就執行大括號 { } 裡面的動作,否則就執行 else 後面的動作。

條件不只有兩個怎麼辦?

  • 若是條件不只兩個,可以用下面的方式:

    var age = 年齡
    
    if ( age === 18 ) {           
    // 如果滿足 age === 18
        console.log("你剛成年唷!")
    } else if ( age <= 18 ) {     
    // 若上面條件不滿足,再判斷是否滿足 age <= 18 
        console.log("你未成年喔!") 
    } else {
    // 若上面條件通通不滿足
        console.log("你成年了!")
    }
    

第二種條件表示方式:switch (這個條件判斷其實不常用)

如果太多太多選擇了,可以利用 switch

  var month = 1 

  switch ( month ) {
  case 1 :                     // 若滿足 month === 1
      console.log("一月")
      break
  case 2 :                     // 若滿足 month === 2        
      console.log("二月")
      break
  case 3 :                     // 若滿足 month === 3 
      console.log("三月")
      break
           .
           .
           .
  default :                     // 若上面條件通通都不滿足
      console.log("輸入的月份有誤")

  }

switch 的條件下,就算第一個 case 已經滿足了,程式還是會一直執行下去,所以每一個條件最後都要加一個 break,告訴電腦我要跳出條件判斷。

第三種條件表示方式:三元運算子

  • 語法:condition? A : B

    • 判斷 condition 如果為 true 就回傳 A
    • 判斷 condition 如果為 false 就回傳 B
  • 舉一個成績判斷為例子:

var score = 70;
var result;

if ( score >= 60 ) {
    result = pass
} else {
    result = fail
}
  • 換成以 三元運算子 來表示:
var score = 70
var result = score >= 60 ? pass : fail

後言

因為三元運算子的程式碼非常簡潔,一開始學習三元運算子真的覺得超級不直觀,想半天都搞不懂這行程式碼是什麼鬼。一開始練習題目還是會以 if, else 為主,但有空還是要強迫自己熟悉三元運算子的寫法,看那些厲害的高手寫程式都是用簡潔的方式寫。


#javascript #變數 #條件







Related Posts

DJI Tello 的基礎操作與套件

DJI Tello 的基礎操作與套件

week4 作業繳交!

week4 作業繳交!

How to solve the perpetual loading issue in Evernote? Evernote 一直轉圈圈的解決辦法

How to solve the perpetual loading issue in Evernote? Evernote 一直轉圈圈的解決辦法


Comments