iT邦幫忙

1

[鼠年全馬鐵人挑戰] Week08 - JavaScript基礎學習心得 part2

陣列與物件

上一次提到的都是單一值的變數, 也就是變數內只會放一個值
接著要來說明陣列(Array)物件(Object)
很多時候會需要用到多個值, 就可以使用陣列或是物件來存放
換句話說, 陣列與物件可以理解為 「可一次存放多個資料的容器」

陣列

陣列是用中括號[]來包住內容的寫法, 且內容不限定型別, 以逗號區隔, 例如:

var myArray = ['我是', '大', '帥哥', 1, '號', function(){ console.log('Hi~') }];

註: 雖然可以什麼都塞進去, 但實務上幾乎不會這麼使用
陣列的索引是從0開始計算, 以myArray來說, "我是"就是第0個值, "大"就是第1個, "帥哥"就是第2個, 依此類推
假設如果要取出值並組合成"我是帥哥1號", 可以這樣取:

var thisistrue = myArray[0] + myArray[2] + myArray[3] + myArray[4]
console.log(thisistrue); // '我是帥哥1號'

必須再強調一次, 陣列比較適合存放相同型態的值, 且實務上並不會這麼使用, 所以只能現在在這邊愉悅自己一下/images/emoticon/emoticon25.gif/images/emoticon/emoticon25.gif/images/emoticon/emoticon25.gif

物件

物件是用大括號{}來包住內容, 內容寫法是一個key對應一個value為一組, 以逗號區隔, 例如:

var myObject = {
    myId: 'A123456789',
    myName: '王小明',
    myAge: 20,
    getMyAge: function() {
        console.log(this.myName + '今年' + this.myAge + '歲');
    }
};

物件寫法非常直覺, 取出的方法也是, 只要抓到物件內的key就能對應到值:

console.log(myObject.myName); // '王小明'
console.log(myObject.myId); // 'A123456789'
console.log(myObject.myAge); // 20
console.log(myObject.getMyAge()); // '王小明今年20歲'

相較陣列來說, 物件比較雜食性, 適合存放不同型態的內容

此時聰明如我馬上就想到**「是不是可以將陣列與物件兩者合併?」**
答案當然是可以的, 且實務上經常使用到

假設今天做一個遊戲, 遊戲中會出現許多道具, 每個道具有自己的詳細資料, 在包包內的道具就可以這樣寫:

var myBag = [{
    id: 'item001',
    name: '暴風神弓',
    rank: '稀有',
    number: 1
},{
    id: 'item306',
    name: '敏捷手套',
    rank: '史詩',
    number: 1
},{
    id: 'item078',
    name: '精靈之木',
    rank: '一般',
    number: 76
},
...];

假設我想把物品籃第一格的暴風神弓拿去丟掉, 就這樣寫:

var myItem = myBag[0]; // 注意 第一格索引是0

function goToTrashCan(item){
    console.log('成功將 ' + item.rank + item.name + ' 丟到垃圾桶'); //
}

goToTrashCan(myItem); // '成功將 稀有暴風神弓 丟到垃圾桶'

控制判斷

接著來紀錄控制判斷內容
很多時候甚至是日常生活中, 都會做到流程控制與判斷, 例如今天我口渴了, 就會去喝水, 我餓了, 就去吃東西, 手癢了, 就來打程式(瘋了?)
javascript的世界, 上面的例子就可以轉換成:

if(口渴) {
    喝水
} else if(餓了){
    吃東西
} else {
    睡覺
}

從上面的例子可以發現, 不是在吃就是在睡, 豬阿?
if ... else if ... else ...就是控制判斷的其中一種方式
另外switch也是控制判斷的一種方式, 不是Nintendo Switch喔, 不要偏心我也寫一個switch的版本:

switch(大腦的想法){
    case 口渴:
        去喝水吧
        break;
    case 餓了:
        去吃X吧
        break;
    default:
        睡覺
        break;
}

if、else if、else

知道控制判斷的概念之後, 來詳細探討它的內容吧
if顧名思義是指「如果達成條件,就做什麼事」

  • if判斷的寫法為: if(條件){要做的內容}
  • else if寫法跟if一樣: else if(條件){要做的內容}
  • else就不需要條件,且要放在最後,如果上面條件都沒達成,就會跑else: else{要做的內容}
    把他們合起來, 會長這樣:
if(條件1) {
    // 達成條件1之後要做的內容
} else if(條件2) {
    // 達成條件2之後要做的內容
} else {
    // 條件1和條件2都沒達成就做這邊的內容
}

註: else ifelse都是不一定需要的, 一個if判斷式中可以只寫if就好

比較運算子

前面說到條件, 到底條件長什麼樣子?
條件是以true或是false來判斷是否達成
但是通常不會直接寫 if(true) { //dosomething }, 這樣寫等於沒寫
這時候就會在條件內用到 比較運算子

比較運算子有以下幾種:

  • 等於: ==
  • 不等於: !=
  • 大於: >
  • 小於: <
  • 大於等於: >=
  • 小於等於: <=
  • 嚴格等於: ===
  • 嚴格不等於: !==

在符合條件時會返回true, 不符合條件時返回false
舉幾個簡單的範例:

console.log('1<2 的結果為:' + (1<2)); // 1<2 的結果為:true
// 1 確實小於 2

console.log('1+1==2 的結果為:' + (1+1==2)); // 1+1==2 的結果為:true
// 1+1 確實等於 2
// 不過這邊要注意不是用1個等於, 1個等於是變數賦予值的意思, 要用2個等於才是比較運算子

console.log('"王小明"=="王小明" 的結果為:' + ("王小明"=="王小明")); // "王小明"=="王小明" 的結果為:true
// 字串比較當然也是可以的

console.log('"王小明"!="王小明" 的結果為:' + ("王小明"!="王小明")); // "王小明"!="王小明" 的結果為:false

再來, 前面有提到 嚴格等於嚴格不等於 , 與 等於不等於 有什麼差異呢?
在正常使用下是沒有差的, 例如:

console.log(1+1==2); // true
console.log(1+1===2); // true

console.log("王小明"=="王小明"); // true
console.log("王小明"==="王小明"); // true

那什麼是不正常的使用呢? 像是這樣:

console.log(1+1 == '2'); // true
console.log(false == 0); // true
console.log(true == 1); // true

1+1等於2沒錯, 但為什麼也等於字串的'2'呢?
且為什麼false等於數字0? true又等於數字1?
顛覆世界顛覆常理阿!

自動轉型

之所以在剛才比較的結果會很奇怪的原因是因為「在一般的等於(==)比較下, 兩側型別不同時, 它會幫忙做「自動轉型」的動作

  • 如果是字串跟數字比較, 會先嘗試把字串轉為數字, 再去做比較
  • 如果其中一邊為布林值, 則會將布林值轉為數字0或1

所以在剛才的情況下, 字串與布林都被轉型, 比較結果就會與一般所想的不太一樣

那我們一般人在使用時, 邏輯沒有那麼強的情況下很容易就會出錯
這時就可以用嚴格的寫法來避免掉(JavaScript真是貼心), 例如:

console.log(1+1 === '2'); // false

邏輯運算子

邏輯運算子也是常用在判斷式內的運算子, 但他不會單獨出現在判斷式條件內, 而是會跟條件搭配使用
邏輯運算子有以下3種:

  • AND(&&): 放於兩個條件中間, 如果左右條件都為true則返回true, 但其中一個為false則返回false
console.log(1<2 && 5>3); // true
// 左邊條件: 1<2為true ,右邊條件: 5>3為true, 結果為true
console.log(1>2 && 5>3); // false
// 左邊條件: 1<2為false ,右邊條件: 5>3為true, 結果為false
  • OR(||): 放於兩個條件中間, 只要左右條件其中一個為true則返回true, 都為false時才返回false
console.log(1>2 || 5>3); // true
// 左邊條件: 1>2為false ,右邊條件: 5>3為true, 結果為true
console.log(1>2 || 5<3); // false
// 左邊條件: 1>2為false ,右邊條件: 5<3為false, 結果為false
  • NOT(!): 放於條件左側, 當條件為true時返回false, 為false時返回true
console.log(!(1>2)); // true

最後來寫個飯粒, 假設我在遊戲中的包包內的道具有這些:

var myBag = [{
    id: 'item001',
    name: '暴風神弓',
    rank: '稀有',
    number: 1
},{
    id: 'item306',
    name: '敏捷手套',
    rank: '史詩',
    number: 1
},{
    id: 'item078',
    name: '精靈之木',
    rank: '一般',
    number: 76
}];

今天我想把稀有度為史詩以外的且數量為2個以上的道具丟掉(到底有多想丟東西), 就可以在goToTrashCan的function裡面這樣判斷:

function goToTrashCan(item){
    if(item.rank !== '史詩' && item.number >= 2) {    
        console.log('成功將 ' + item.rank + '-' + item.name + ' 丟到垃圾桶');
    }else {
        console.log(item.rank + '-' + item.name + ' 不符合條件');
    }
}

寫好之後, 把每一個item都丟進去判斷

goToTrashCan(myBag[0]); // '稀有-暴風神弓 不符合條件'
goToTrashCan(myBag[1]); // '史詩-敏捷手套 不符合條件'
goToTrashCan(myBag[2]); // '成功將 一般-精靈之木 丟到垃圾桶'

這樣就完成了~


眼尖的朋友應該會有發現超沒效率的寫法吧?
連續寫了三次幾乎一樣的程式碼, 如果有100個道具要判斷, 是否要寫100行?
下週會來紀錄可以用迴圈的方式來解決此問題~


尚未有邦友留言

立即登入留言