我的第一堂 - 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

建立學習心態

建立學習心態

 關於GitHub

關於GitHub

Babel 入門:用 Babel 轉換太潮的 JavaScript

Babel 入門:用 Babel 轉換太潮的 JavaScript


Comments