Phaser -- HTML 遊戲框架

附註:JavaScript 簡介

(1) JavaScript 簡介

∗ JavaScript

▸ 瀏覽器端 (客戶端) 程式語言程式 (Client-side scripting language)

▸ 主要在瀏覽器環境中執行 (亦即在網頁中執行),但漸漸發展到在其他環境亦可執行

▸ 1995年由 Netscape 工程師 Brendan Eich 所研發

▸ 原先擬命名為 LiveScript,但因錯誤追求 Java 程式語言時尚而命名為 JavaScript,與 Java 其實沒有關係

▸ 語法來自 Java 與 C 語言

(2) 文字編輯器

∗ HTML 文件及 JavaScript 都是純文字檔

▸ 使用文字編輯器編輯

▸ 常用的文字編輯器: Sublime Text 3, Brackets, Atom, Bluefish, notepad++

∗ 下載、安裝、及設定 Brackets:http://brackets.io/

▸ 設定中文繁體介面:Debug → Switch Language → 繁體中文 → Reload Brackets

▸ 選擇字型:檢視 → 佈景主題 → 字體大小:14px,字體(選等寬字體):

✶ Ubuntu:DejaVu Sans Mono
✶ Windows:Consolas

▸ 設定按下 Tab 鍵的結果是輸入 2 個空白,而不是定位鍵

✶ 點選右下方設定:最後呈現「空白字元:2」
✶ 註:在空白處移動游標時,看起來還是一次移動 2 格 (感覺上還是輸入了定位鍵),這是 Brackets 的智慧功能,一次跳至所設定空白字元的數量

(3) JavaScript 程式的位置

∗ 直接撰寫在網頁中,由 <script> 與 </script> 標籤包含,例如:

▸ index.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript範例</title>
</head>
<body>
...

<script>
alert('Hello world');
</script>
</body>
</html>

▸ 由於網頁各個元素的載入有其順序,JavaScript 程式應放在網頁最後 (亦即 </body> 之前),以確保網頁所有元素都載入完畢, 才載入 JavaScript 程式

∗ 撰寫在獨立檔案,在網頁中透過連結存取,例如:

▸ index.js

alert('Hello world');

▸ index.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript範例</title>
</head>
<body>
...

<script src="js/index.js"></script>
</body>
</html>

▸ JavaScript 的連結亦應放在網頁最後 (亦即</body>之前),以確保網頁所有元素都載入完畢,才載入 JavaScript 程式

▸ 將 Java 撰寫在獨立檔案比寫在網頁中較好

✶ 避免與 HTML 程式碼混雜
✶ JavaScript 程式只會載入一次,但網頁會隨著使用者點選而多次載入,將程式放在網頁中造成不必要的多次下載

(4) 目錄結構、網頁、及程式檔

∗ 常用的目錄結構:

<folderName>/
    index.html
    js/
        index.js

▸ index.html內容:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript範例</title>
</head>
<body>
<script src="js/index.js"></script>
</body>
</html>
✶ 在</body>標籤之前以<script ...></script>標籤載入 index.js 程式檔
✶ 將所有 JavaScript 程式寫在 index.js 檔中

∗ 程式偵錯

▸ 在 Firefox 或 Chrome 瀏覽器按下 F12,可進入程式偵錯畫面

▸ JavaScript 指令 console.log (<varName>) 可在偵錯區的 Console (主控台) 顯示變數值

(5) 警示

∗ 警示 (Alert):彈出視窗顯示警示訊息

▸ 例如:alert('謝謝您的意見');

(6) 字串 (String)

∗ 設定字串變數

var deptName = '資訊管理系';

▸ 更改變數值

alert(deptName);
deptName = '資訊工程系';
alert(deptName);

∗ 單引號或雙引號

▸ JavaScript的字串可使用單引號 (') 或雙引號 (") 包含,但單引號較簡單、較常用

▸ 字串本身有單引號或雙引號,則可分別使用雙引號或單引號包含,例如:

message = 'The book called "Learning JavaScript" is my favorite.';
message = "It's popular to use JavaScript to create effects in a web page.";

∗ 連結字串

▸ 使用 + 號連結字串,例如:

var username = 'Mark';
alert('謝謝您, ' + username + '先生/小姐!');

(7) 數值 (Number)

∗ 設定數值變數及數值運算

var myWeight = 65;
var MarksWeight = myWeight + 5;
alert("Mark's weight: " + MarksWeight + ' Kg.');      // 70

▸ 字串加數值等於字串

myWeight = '65';
MarksWeight = myWeight + 5;
alert("Mark's weight: " + MarksWeight + ' Kg.');    // '655'

(8) 變數名稱 (Variable name)

∗ JavaScript 保留字

abstractarguments booleanbreakbyte
casecatchcharclass*const
continuedebuggerdefaultdeletedo
doubleelseenum*evalexport*
extends*falsefinalfinallyfloat
forfunctiongotoifimplements
import*ininstanceofintinterface
letlongnativenewnull
packageprivateprotectedpublicreturn
shortstaticsuper*switchsynchronized
thisthrowthrowstransienttrue
trytypeofvarvoidvolatile
whilewithyield

▸ 保留字不得用於變數名稱


∗ JavaScript 變數命名規則

▸ 不能有空格

▸ 只能包含英文字母、數字、錢號 ($)、底線,但不能以數字開頭

▸ 大小寫字母有區別

▸ 一般使用駝峰式 (Camel case) 命名方式

▸ 變數名稱應該有意義

(9) 註解 (Comment)

∗ 單行://

∗ 多行:/* ... */

(10) 數學運算式

∗ 基本數學運算式

var num = 4;    // 設值 (Assignment)
num = 2 + 2;    // 加 (Addition)
num = 8 - 6;    // 減 (Subtraction)
num = 2*2;      // 乘 (Multiplication)
num = 8/2;      // 除 (Division)
num = 10%6;     // 餘數 (模數,Modulus)

∗ 加 1 及減 1

num++;          // 加 1 (Increment: num = num + 1;)
num--;          // 減 1 (Decrement: num = num - 1;)
numA = num++;   // 先設值然後加 1
numA = num--;   // 先設值然後減 1
numA = ++num;   // 先加 1 然後設值
numA = --num;   // 先減 1 然後設值

(11) 提示框

∗ 提示框 (Prompt box)

▸ 提示問題並接受使用者的輸入,亦可加入預設值

var sport = prompt('喜愛的運動?');
var sport = prompt('喜愛的運動?', '棒球');

▸ 範例1:

var sport = prompt('喜愛的運動?', '棒球');
alert('我也愛' +  sport);

▸ 範例2:

var numCats = prompt('寵物店有幾隻貓?');
alert('再加一隻就有' +  (numCats+1) + '隻');
→ 若輸入 5,結果為 51 隻
✶ 所有使用者回覆的資料都是字串,如果未輸入資料,變數值就是空字串 ('')

(12) If 指令

∗ If 指令

if <condition> {
  ...
}
if <condition> {
  ...
} else {
  ...
}
if <condition> {
  ...
} else if {
  ...
} else {
  ...
}
if <condition> {
  if <condition> {
    ...
  } else if {
    ...
  } else {
    ...
  }
} else {
  ...
}

(13) 比較運算子 (Comparison operator)

∗ 相等運算子 (Equality operator):=== (三個等號)

▸ 可比較變數是否等於字串、數值、數學計算式、或另一變數

if (fullName === 'Mark' + ' ' + 'Mayers') {
  ...
}
if (fullName === firstName + ' ' + lastName) {
  ...
}
if (totalCost === 81.5 + 135) {
  ...
}
if (totalCost === materialCost + laborCost) {
  ...
}

▸ 一般情況下,亦可使用二個等號:==

✶ 二個等號較鬆散:資料型態雖不同,但如果意義相同即視為相同
✶ 三個等號較嚴格:資料型態不同即視為不同
✶ 例如:
0 == false      // true
0 === false     // false,因為資料型態不同
1 == '1'        // true,因為資料型態會自動轉換
1 === '1'       // false,因為資料型態不同
null == undefined      // true
null === undefined     // false
'0' == false    // true
'0' === false   // false

∗ 不相等運算子 (Not-equal operator):!==

▸ 可比較變數是否等於字串、數值、數學計算式、或另一變數

if (yourTicketNum !== 487208) {

▸ 一般情況下亦可使用一個等號:!=

∗ 大於運算子 (Greater than operator):>

if (numStudents > 30) { ...

∗ 小於運算子 (less than operator):<

if (numStudents < 30) { ...

∗ 大於等於運算子(Greater than operator):>=

if (numStudents >= 30) { ...

∗ 小於等於運算子 (Greater than operator):<=

if (numStudents <= 30) { ...

∗ 練習 1:

var x = prompt('天主教教宗住在哪裡?');
if (x=='梵蒂岡') {
  alert('正確');
} else {
  alert('錯誤');
}

∗ 練習 2:

var x = prompt('天主教教宗住在哪裡?');
if (x=='梵蒂岡') {
  alert('正確');
} else if (x=='羅馬') {
  alert('錯誤,但很接近了');
} else {
  alert('錯誤');
}

∗ 註:JavaScript 的縮排一般為 2 個空格

(14) 邏輯運算子 (Logical operator)

∗ 而且運算子 (And operator):&&

if (weight>60 && weight<80) {

∗ 或者運算子 (Or operator):||

if (weight<60 || weight>80) {

∗ 練習:

var age = prompt('您的年紀:');
if (7<age && age<12) {
  alert('您是國小生');
} else if (12<=age && age<15) {
  alert('您是國中生');
} else if (15<=age && age<18) {
  alert('您是高中生');
}

(15) 陣列 (Array)

∗ 不使用陣列:

var city0 = '台北市';
var city1 = '新北市';
var city2 = '台中市';
var city3 = '台南市';
var city4 = '高雄市';

∗ 使用陣列 (以方括號包含):

var cities = ['台北市', '新北市', '台中市', '台南市', '高雄市'];
alert('我最喜歡的城市:' + cities[2]);

▸ 陣列變數名稱大多使用複數

▸ 陣列元素索引 (Index) 從 0 開始

▸ 陣列元素可以有不同的資料型態

var mixedData = [26, '學生', 2, '教師'];

∗ 增加或修改陣列元素

var pets = [];    // 宣告一個空陣列
pets[2] = '蜥蜴'
pets[3] = '蛇';
alert(pets[0]);    // 未定義:undefined
alert(pets[2]);    // 蜥蜴

▸ 增加元素:

pets[4] = '狗';    // 原先元素僅有 4 個,增加第 5 個

▸ 修改已存在之元素:

pets[3] = '貓';    // 修改第 4 個元素

▸ 設定未定義之元素:

pets[0] = '鳥';    // 設定未定義之第 0 個元素
pets[1] = '魚';    // 設定未定義之第 1 個元素

∗ 在陣列頭尾增加或刪除元素

▸ 刪除第一個元素:shift()

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.shift();
alert(pets);    //  魚,蜥蜴,蛇,狗

▸ 在陣列開頭增加元素:unshift()

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.unshift('兔子');
alert(pets);    // 兔子,鳥,魚,蜥蜴,蛇,狗
pets.unshift('烏龜', '布丁鼠');
alert(pets);    // 烏龜,布丁鼠,兔子,鳥,魚,蜥蜴,蛇,狗

▸ 刪除最後一個元素:pop()

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.pop();
alert(pets);    // 鳥,魚,蜥蜴,蛇

▸ 在陣列結尾增加元素:push()

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.push('兔子');
pets.push('烏龜', '布丁鼠');
alert(pets);    // 鳥,魚,蜥蜴,蛇,狗,兔子,烏龜,布丁鼠

∗ 在陣列中插入或刪除元素

▸ 在陣列中插入一個或多個元素 (「拼接」):splice(<startIndex>, <numElemToRemove>, <elements>)

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.splice(2, 0, '烏龜');    // 在位置 2 刪除 0 個元素 ,插入'烏龜'
alert(pets)     // 鳥,魚,烏龜,蜥蜴,蛇,狗

▸ 在陣列中刪除某元素:splice(<startIndex>, <numElemToRemove>)

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.splice(2, 1);
alert(pets)     // 鳥,魚,蛇,狗
var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.splice(2, 2);
alert(pets)     // 鳥,魚,狗

▸ 在陣列中同時刪除及插入元素

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
pets.splice(1, 2, '貓', '鴨');  // 在位置 1 刪除 2 個元素,插入'貓', '鴨'
alert(pets)     // 鳥,貓,鴨,蛇,狗

∗ 串接兩個陣列:concat()

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
var morePets = ['烏龜', '布丁鼠'];
var allPets = pets.concat(morePets);
alert(allPets);    //  鳥,魚,蜥蜴,蛇,狗,烏龜,布丁鼠

∗ 陣列切片:slice(<startIndex>, <endIndexPlusOne>)

var pets = ['鳥', '魚', '蜥蜴', '蛇', '狗'];
var somePets = pets.slice(1, 3)
alert(somePets);    // 魚, 蜥蜴

(16) For 迴圈 (Loop)

∗ For 迴圈 (For loop),例如:

var cities = ['台北市', '新北市', '台中市', '台南市', '高雄市'];
for (var i=0; i<5; i++) {
  alert(cities[i]);
}
或:
for (var i in cities) {
  alert(cities[i]);
}

▸ 範例:

var cities = ['台北市', '新北市', '台中市', '台南市', '高雄市'];
var index = -1;
var cleanestCity = prompt('最乾淨的城市:');

for (var i=0; i<5; i++) {
  if (cleanestCity == cities[i]) {
    index = i;
    break;
  }
}
if (index>=0) {
  alert('在清單中的第' + index + '個位置');
} else {
  alert('不在清單中');
}

▸ 利用陣列長度控制迴圈:cities.length

for (var i=0; i<cities.length; i++) {
  ...
}

∗ 巢狀 For 迴圈 (Nested for loop)

for (var i=0; i<...; i++) {
  for (var j=0; j<...; j++) {
    ...
  }
}

(17) 字串進階功能

∗ 改變英文字母大小寫

▸ 英文字母分大小寫,例如居住城市:New York, new York, NEw YOrK, …

▸ 為求正確比對,通常全轉為小寫 (.toLowerCase()) 再儲存,比對時亦先將使用者的輸入轉為小寫

▸ 範例:

var cityToCheck = prompt('Enter your city: ');
cityToCheck = cityToCheck.toLowerCase();
var cleanestCities = ['new york', 'seatle', 'san francisco', 'boston', 'pittsburgh'];
for (var i=0; i<=cleanestCities.length; i++) {
  if (cityToCheck==cleanestCities[i]) {
    alert('It is one of the cleanest cities.');
  }
}

▸ 改為全大寫:.toUpperCase()

∗ 尋找特定字串:.indexOf(<someString>)

▸ 範例:將 World War II 改為 the Second World War

var text = 'This is an article about World War II, and it is very touching.';
var firstChar = text.indexOf('World War II');
alert(text);
if (firstChar!=-1) {
  text = text.slice(0, firstChar) + 'the Second World War' + text.slice(firstChar+12);
}
alert(text);

.indexOf() 尋找字串第一次出現的位置,最後一次出現的位置:.lastIndexOf()

▸ 亦可使用字串取代函式:.replace(<stringToBeReplaced>, <ReplacingString>)

✶ 取代第一次出現字串
var newText = text.replace('World War II', 'the Second World War');
✶ 取代所有字串 (Global replacement)
var newText = text.replace(/World War II/g, 'the Second World War');

∗ 字串中字元位置:.charAt(<index>)

▸ 範例:尋找驚嘆號"!"

for (var i=0; i<text.length; i++) {
  if (text.charAt(i)=='!') {
    alert('找到驚嘆號');
    break;
  }
}

(18) 數字進階功能

∗ 四捨五入:Math.round(<someNumber>)

▸ 範例:將平均分數四捨五入

var avgScore = 78.67;
avgScore = Math.round(avgScore);
alert(avgScore);    // 79

avgScore = 78.27;
avgScore = Math.round(avgScore);
alert(avgScore);    // 78

∗ 地板運算:Math.floor(<someNumber>)

▸ 範例:將平均分數無條件捨去

var avgScore = 78.67;
avgScore = Math.floor(avgScore);
alert(avgScore);    // 78

∗ 天花板運算:Math.ceil(<someNumber>)

▸ 範例:將平均分數無條件進入

var avgScore = 78.67;
avgScore = Math.ceil(avgScore);
alert(avgScore);    // 79

∗ 隨機變數 (Random number):Math.random()

▸ 產生範圍在0.000...000 ~ 0.999...999 (16 位小數) 的隨機數值

▸ 擲骰子應用:產生 1 ~ 6 的隨機數字

var bigDecimal = Math.random();
var outCome = Math.floor(bigDecimal*6 + 1);

▸ 擲 10 次骰子

for (var i=0; i<10; i++) {
  alert(Math.floor(Math.random()*6 + 1));
}

∗ 將數字字串轉為數值

▸ JavaScript 在進行數學運算時 (加法除外),會自動將「數字字串」轉為數值,例如:

var num1 = '32';    // 字串
var num2 = 20;      // 數字
var total = num1 - num2;
alert(total);    // 12

▸ 如果數學運算為加法,則會將數值轉為數字字串然後串連

var num1 = '32';    // 字串
var num2 = 20;      // 數字
var total = num1 + num2;
alert(total);    // '3220'

▸ 若使用文字字串進行數學運算,則產生 NaN 結果 (Not a number)

var num1 = 'dog';
var num2 = '20';
var total = num1 - num2;
alert(total);    // Nan

▸ 常犯錯誤:使用者的輸入一定是字串

var age = prompt('輸入您的年齡:');    // 輸入:22
var agePlusOne = age + 1;
alert(agePlusOne);    // '221'
✶ 解決方案:利用parseInt(<numString>) 將數字字串轉為整數
var agePlusOne = parseInt(age) + 1;
alert(agePlusOne);    // 23
✶ 數字字串轉為浮點數:parseFloat(<numString>)

▸ 不論整數或浮點數,將數字字串轉為數值:Number(<numString>)

▸ 將數值轉為字串:.toString(<num>),例如:

var num = 22;
var numString = num.toString();    // '22'

(19) 日期與時間

∗ 日期物件 (Date object):使用者電腦作業系統的時間

var rightNow = new Date();
alert(rightNow);    // E.g., Sat Aug 29 2015 09:58:31 GMT+0800 (CST)

▸ 包含欄位:星期、月、日、年、時、分、秒、格林威治時差 (Greenwich Mean Time offset)、時區 (China Standard Time)

∗ 取出日期各項資料

▸ 星期:getDay()

var rightNow = new Date();
var day = rightNow.getDay();  // 值:0 ~ 6:星期日 ~ 六
var dayNames = ['星期日', '星期一 ', '星期二 ', '星期三', '星期四', '星期五', '星期六']
alert(dayNames[day]);

▸ 日:getDate();        // 值:1 ~ 31

▸ 月:getMonth();      // 值:0 ~ 11

▸ 年:getFullYear();   // 值:e.g., 2015

▸ 時:getHours();       // 值:0 ~ 23

▸ 分:getMinutes();    // 值:0 ~ 59

▸ 秒:getSeconds();    // 值:0 ~ 59

▸ 微秒:getMilliseconds();    // 值:0 ~ 999

▸ 從 1970/1/1 午夜到現在共歷經多少微秒:getTime();

∗ 設定日期時間

▸ 設定日期

var theDate = new Date('June 30, 2035');     // Tue Jun 30 2015 00:00:00 GMT+0800 (CST)

▸ 設定日期及時間

var theDate = new Date('June 30, 2035 13:25:00');  // Tue Jun 30 2015 13:25:00 GMT+0800 (CST)

▸ 範例:計算總日數,從現在開始到 2035/6/30 共有多少天?

var msDiff = new Date('June 30, 2035').getTime() - new Date().getTime();
var numDays = Math.floor(msDiff/(1000*60*60*24));
alert(numDays);

∗ 設定日期各項資料

var theDate = new Date();

▸ 設定年:theDate.setFullYear(2006);   // 設為2006年

▸ 設定月:theDate.setMonth(6);           // 設為7月

▸ 設定日:theDate.setDate(6);             // 設為6日

▸ 設定時:theDate.setHours(6);           // 設為6點

▸ 設定分:theDate.setMinutes(6);        // 設為6分

▸ 設定秒:theDate.setSeconds(6);        // 設為6秒

▸ 設定微秒:theDate.setMilliseconds(6);    // 設為6微秒

(20) 函式

∗ 函式 (Function):可供其他程式呼叫而重複執行的程式片段

▸ 例如:顯示現在時間的函式

function tellTime() {
  var now = new Date();
  var theHr = now.getHours();
  var theMin = now.getMinutes();
  alert('現在時間:' + theHr + ':' + theMin);
}

▸ 呼叫函式:

tellTime();

∗ 函式參數

▸ 函式可以接受由呼叫程式傳來的參數,例如:

function greetUser(username) {
  alert('嗨' + username + ',您好!');
}
...
greetUser('Johnny');

▸ 呼叫程式所提供的參數稱為argument

▸ 函式端接受傳來的參數稱為parameter

∗ 函式回傳值

▸ 函式可以回傳資料給呼叫程式,例如:

✶ 如果商品總價 (Merchandise total) 大於或等於 5,000 元,訂單總價 (Order total) 即為商品總價
✶ 如果商品總價小於 2,000 元,訂單總價為商品總價加 200 元
✶ 如果商品總價介於 2,000 ~ 5,000 元,訂單總價為商品總價加 200 元再加超過 2,000 元部份的百分之三
function calcTotal(merchTotal) {
  var orderTotal;
  var top = 5000;
  var bottom = 2000;
  var baseRate = 200;
  if (merchTotal>=top) {
    orderTotal = merchTotal;
  } else if (merchTotal<bottom) {
    orderTotal = merchTotal + baseRate;
  } else {
    orderTotal = merchTotal + baseRate + 0.03*(merchTotal-bottom);
  }
  return orderTotal;
}

alert(calcTotal(6000));    // 6000
alert(calcTotal(1500));    // 1700
alert(calcTotal(4000));    // 4260

∗ 區域與全域變數

▸ 全域變數 (Global variable):變數宣告在程式主體中,任何地方都能使用

▸ 區域變數 (Local variable):變數宣告在函式中 (包括傳入參數),僅在函式中能使用

▸ 例如:以下 total 為全域變數,subTotal 為函式中的區域變數

var total = 0;

function calcTotal(merchTotal) {
  var subTotal;
  if (merchTotal>5000) {
    subTotal = merchTotal;
  } else {
    subTotal = merchTotal*(1+0.03);
  }
  total += subTotal;    // 全域變數在函式中亦能使用
}

alert(total);      // 0 (全域變數在任何地方都可使用)
calcTotal(2000);
alert(total);      // 2060
alert(subTotal);   // Error: not defined (區域變數在函式以外無法使用)

▸ 全域變數名稱若與區域變數名稱相同,則為兩個不同的物件,例如:

var total = 0;    // 全域變數

function calcTotal(merchTotal) {
  var total;     // 區域變數
  if (merchTotal>5000) {
    total = merchTotal;
  } else {
    total = merchTotal*(1+0.03);
  }
  alert(total);    // 2060 (使用區域變數,全域變數無法使用)
}

alert(total);      // 0 (全域變數)
calcTotal(2000);   // 2060
alert(total);      // 0 (全域變數並未修改)

▸ 若非必要,盡量不要使用全域變數

✶ 在任何地方都能取用全域變數,造成全域變數難以追蹤及維護
✶ 程式應盡量模組化使牽涉的範圍侷限,如此程式才容易了解,有全域變數的程式牽涉過廣
✶ 程式彼此依賴程度應該越少越好,有全域變數的程式依賴性過高
✶ 變數名稱空間 (Namespace) 易受污染:區域變數名稱與全域變數名稱相互混淆
✶ 同步問題 (Concurrency issue):多執行緒的程式可能同時修改全域變數,變數修改程序難以定義
✶ 含有全域變數的程式較難測試,因為不容易建立一個「乾淨」的測試環境來讓每次測試的環境相同

(21) While 迴圈

∗ For 迴圈的使用時機:迴圈數量已知

∗ While 迴圈的使用時機:迴圈數量未知

▸ 語法:

while (<condition>) {
  ...
}

(22) JavaScript 物件

∗ JavaScript 物件 (Object)

▸ 一個 JavaScript 物件變數可以包含許多屬性與值 (Property and value) 的配對

▸ 語法:以一個大括號包含所有屬性與值配對,然後指派給一個物件變數,例如宣告一個汽車物件:

var car = {
  make: 'Toyota',
  color: 'silver',
  year: 2015,
}
✶ 屬性與值之間以冒號指派,屬性與屬性之間以逗號分開
✶ 宣告完成後,就可以利用 <varName>.<propertyName> 的點號方式來存取屬性,例如:
alert(car.make);
alert(car.color);     // silver
car.color = 'black';  // Reset property
alert(car.color);     // black
alert(car.year);      // 2015
car.year = 2016;
alert(car.year);      // 2016
✶ 也可以利用 <varName>['<propertyName'] 方式存取屬性,例如:
alert(car['make']);
alert(car['color']);     // silver
alert(car['year']);      // 2016

▸ 屬性的值亦可為一個函式,稱為該物件的「方法」(Method),例如:

var car = {
  make: 'Toyota',
  type: 'Wish',
  color: 'silver',
  year: 2015,
  setColor: function(color) {
    this.color = color;      // Change the property: color
    this.type = 'Wish';      // Add a new property: type
  },
}
✶ 存取方式為<variable>.<propertyName>()
car.setColor('white');
alert(car.color);        // white
alert(car.type);         // Wish

上一章