JavaScript 與 jQuery

第 3 章    函式與物件

(1) 函式

∗ 函式 (Function)

▸ 將一群指令組合起來成為一個程式區塊 (Code block) 以執行一個特殊功能

✶ 程式區塊以大括號 ({ }) 包含

▸ 如果其他程式也需要執行相同功能,該函式就可以重複使用

▸ 有些函式需要傳入某些資料才能執行,這些資料稱為參數 (Parameter)

▸ 有些函式需要回覆資料給呼叫程式,這些資料稱為回覆值 ( return value)

∗ 一個基本的函式

▸ 建立第 3 章的目錄架構:

javaScript/
   ...
   ch3/
      css/
      img/
      js/

▸ 下載 assets3.zip, 解壓縮後將 ch3.css 置於 ch3/css/ 目錄中, 其餘影像均置於 ch3/img/ 目錄中

▸ 建立 ch3/basic-function.html

<!doctype html>
<html>
<head>
<title>JavaScript Exercise</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/ch3.css">
</head>
<body>
<h1></h1>
<div id="message">歡迎蒞臨本站</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/basic-function.js"></script>
</body>
</html>

▸ 建立 ch3/js/basic-function.js

$(document).ready(function() {

  var msg = '請註冊以收到我們的 9 折價格新訊息';

  updateMessage();

  function updateMessage() {
    $('#message').html(msg);
  }

});
✶ 定義 updateMessage() 函式,利用 $('#message') 取得目標元素, 再利用 .html() 方法來設定元素的內容

∗ 函式定義 (Function definition)

▸ 格式如下:以 function 開頭,命名函式名稱 <funName>, 接著左右小括號,接著由左右大括號包含程式區塊,內含本體程式

function <funName>() {
  ...
}

▸ 例如:

function sayHello() { u
  document.write('Hello');
}

∗ 呼叫函式 (Calling/Invoking a function )

▸ 直接以函式名稱後接左右小括號來呼叫函式:

<funcName>(); 
✶ 例如: sayHello();

∗ 接受參數的函式

▸ 有些函式需要提供相關資訊才能執行,這些資訊稱為參數 (Parameter)

▸ 例如計算長方形面積的函式需要寬與高的參數:

function getArea(width, height) {
  return width * height;
}
✶ 以上的 widthheight 稱為 Parameter

▸ 呼叫函式時,需提供實際參數值,例如:

var wallWidth = 20;
var wallHeight = 30;
var area = getArea(wallWidth, wallHeight);
✶ 以上的 wallWidthwallHeight 稱為 Argument

∗ 回覆值的函式

▸ 有些函式會回覆單一資料給呼叫程式,例如上例的 getArea() 函式回覆長方形面積

▸ 函式也可利用陣列回覆多個值,例如:

function getSize(width, height, depth) {
  var area = width * height;
  var volume = width * height * depth;
  var sizes = [area, volume];
  return sizes;
}
var areaAndVolume = getSize(3, 2, 3)
var area = areaAndVolume[0];      // 取用回覆值的第 0 個元素
var volume = areaAndVolume[1];    // 取用回覆值的第 1 個元素

∗ 具名函式

▸ 為了方便以後多次呼叫,函式在定義的時候會給定名稱,因此稱為具名函式 (Named function):

function <funName>() {
  ... 
}

▸ 具名函式是在解譯時 (Parse time) 產生,且 JavaScript 在執行時,會先搜尋變數宣告與函式定義的資訊, 然後再正式開始執行,因此,可以在函式定義之前呼叫函式,例如:

var size = area(20, 30);
alert(size);

function area(width, height) {
  return width * height;
}

∗ 匿名函式 (Anonymous function)

有兩種:

▸ 函式表示式 (Function expression)

✶ 如果將函式放在應該放表示式的地方,該函式就稱為函式表示式,例如:
var area = function(width, height) {
  return width * height;
}
var size = area(20, 30); 
# 函式儲存在變數 area 中,之後就可以像一般函式一樣被呼叫
✶ 函式表示式沒有函式名稱,沒有名稱的函式稱為匿名函式 (Anonymous function)
✶ 函式表示式是在執行時 (Run time) 產生,因此必須放在呼叫程式之前,例如以下程式會產生錯誤訊息: Uncaught TypeError: area is not a function
var size = area(20, 30);
alert(size);

var area = function(width, height) {
  return width * height;
}

▸ 被立即呼叫的函式表示式 (Immediately invoked function expression, IIFE)

✶ 被立即呼叫的函式表示式沒有函式名稱,而且在定義時就立即被執行,例如:
var area = (function(width, height) {
  var width = 20;
  var height = 30;
  return width * height;
}());
# 整個函式被包在一組小括號之中,說明這是一個表示式
# 函式的結束大括號 (}) 之後另有一組左右小括號,表示要立即執行

∗ 匿名函式的使用時機

▸ 整個程式中只會執行一次函式,不會被重複呼叫

▸ 當作其他函式的參數

▸ 設定某個物件的特性值

▸ 在事件處理器或監聽器中,當某事件發生後執行某項工作

▸ 避免函式名稱相同的衝突問題

∗ 變數有效範圍 (Variable scope)

▸ 區域變數 (Local variable):當變數在一個函數內宣告,就只能在該函式中使用

✶ 亦稱為函式層級變數 (Function-level variable)
✶ 有效範圍為區域範圍 (Local scope),或稱為函式層級範圍 (Function-level scope)
✶ 當函式執行時,區域變數被產生,當函式結束後,區域變數會被刪除
✶ 因為有效範圍為區域性,因此不同的函式可以有相同名稱的區域變數

▸ 全域變數 (Global variable):當變數在函數範圍之外宣告,就能在程式各處使用

✶ 有效範圍為全域範圍 (Global scope)
✶ 只要使用全域變數的網頁還在瀏覽器中,全域變數就永遠存在記憶體中
✶ 全域變數很容易造成變數名稱衝突,盡量避免使用
✶ 未使用 var 而產生的新變數視為全域變數,因此盡量避免如此產生變數

▸ 例如以下程式中, area , width, height 都是區域變數, wallSize 是全域變數

function getArea(width, height) {
  var area = width * height;
  return area;
}

var wallSize = getArea(20, 30);
docuument.write(wallSize); 

∗ 變數與記憶體

▸ 區域變數在函式結束後即刪除

▸ 全域變數長期存在並佔據記憶體,只要網頁還在瀏覽器就必須記住它們

▸ 變數越多,佔據的記憶體越多,瀏覽器的效能就會降低、回應緩慢

▸ 命名碰撞 (Naming collision)

✶ 程式設計師在命名變數時,自己可以控制不使同相同的變數名稱,但一個網站可能由多人共同開發,而且網頁也常常使用第三方程式, 常常發生命名碰撞的問題,例如以下兩個程式片段各宣告一個全域變數 msg ,造成名稱衝突:
// Show size of the painting
function showPaintingSize() {
  var width = 20;
  var height = 30;
  return 'Painting size: ' + (width*height);
} 

var msg = showPaintingSize();

// Show size of the garden
function showGardenSize() {
  var width = 15;
  var height = 20;
  return 'Garden size: ' + (width*height);
} 

var msg = showGardenSize();
✶ 解決方案:不要使用全域變數

▸ 作業 1

(2) 物件

∗ 物件 (Object)

▸ 物件將變數與函式組在一起形成一個模型 (Model),用來描述真實世界的東西

▸ 在物件中,變數稱為特性 (Property),函式稱為方法 (Method)

▸ 物件的特性及方法都是鍵 (Key) 與值 (Value) 的配對,以冒號隔開,各配對之間以逗號隔開

▸ 在物件中,若要存取自己的特性或方法,需使用 this.<keyName> 的格式,其中 this 指的就是自己

▸ 例如:

var hotel = {
  name: '朝陽飯店',
  rooms: 40,
  booked: 25,
  gym: true,
  roomTypes: ['twin', 'double', 'suite'], 
  checkAvailability: function() {
    return this.rooms - this.booked;
  }
};

▸ 利用以上格式建立物件,稱為字面表示法 (Literal notation)

▸ 歸納:

✶ Properties:
KEY VALUE TYPE
name 朝陽飯店 string
rooms 40 number
booked 25 number
gym true Boolean
roomTypes ['twin', 'double', 'suite'] array
✶ Methods
KEYVALUETYPE
checkAvailability
function() {
  return this.room - this.booked;
}
function

∗ 存取物件的特性或方法

▸ 使用點號表示法 (Dot notation),例如:

var hotelName = hotel.name;
var roomsFree = hotel.checkAvailabilty();
✶ 其中 hotel 是物件 (Object),點號 (.) 稱為成員運算子 (Member operator), namecheckAvailabilty 分別是特性與方法的名稱

▸ 也可以使用方括號的存取格式:

var hotelName = hotel['name'];

∗ 練習:在網頁中顯示飯店名稱及空房數

▸ 建立 ch3/object-literal.html

...
<body> 
<h1></h1>
<div id="info">
  <h2>飯店房間</h2>
  <div id="hotelName"></div>
  <div>尚餘空房</div>
  <div id="rooms"></div>
  <br>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/object-literal.js"></script> 
...

▸ 建立 ch3/js/object-literal.js

$(document).ready(function() {

  var hotel = {
    name: '朝陽飯店',
    rooms: 40,
    booked: 25,

    checkAvailability: function() {
      return this.rooms - this.booked;
    }
  };

  $('#hotelName').html(hotel.name);
  $('#rooms').html(hotel.checkAvailability());

});
✶ 首先利用字面表示法建立 hotel 物件,並設定相關特性與方法
✶ 設定 idhotelName 的 HTML 元素的文字內容為 hotel.name
✶ 設定 idrooms 的 HTML 元素的文字內容為 hotel.checkAvailability()

∗ 利用建構子表示法 (Constructor notation) 建立物件

▸ 首先建立一個空物件,格式如下:

var <varName> = new Object();
✶ 例如: var hotel = new Object() ;
Object() 是 JavaScript 的內建函式,用來建立物件
✶ 也可使用空的大括號方式建立一個空物件,例如: var hotel = {} ;

▸ 接著,為此物件建立特性與方法,例如:

hotel.name = '朝陽飯店';
hotel.rooms = 40;
hotel.booked = 25;
hotel.checkAvailability = function() {
 return this.rooms – this.booked;
}

∗ 練習:利用建構子表示法建立物件

▸ 建立 ch3/object-constructor.html (類似 object-literal.html):

...

<script src="js/object-constructor.js"></script>
...

▸ 建立 ch3/js/object-constructor.js

$(document).ready(function() {

  var hotel = new Object();

  hotel.name = '朝陽飯店';
  hotel.rooms = 40;
  hotel.booked = 25;

  hotel.checkAvailability = function() {
    return this.rooms - this.booked;
  };

  $('#hotelName').html(hotel.name);
  $('#rooms').html(hotel.checkAvailability());

});
✶ 首先利用建構子表示法建立一個空物件
✶ 分別建立物件的特性與方法
✶ 設定 idhotelName 的 HTML 元素的文字內容為 hotel.name
✶ 設定 idrooms 的 HTML 元素的文字內容為 hotel.checkAvailability()

∗ 利用建構表示法產生許多物件

▸ 物件建構子可以將函式當作範本 (Template) 來產生許多同一型態的物件,稱為建構子函式 (Constructor function)

▸ 例如,定義一個 Hotel 函式:

function Hotel(name, rooms, booked) {
  this.name = name;
  this.rooms = rooms;
  this.booked = booked;
  this.checkAvailability = function() {
    return this.rooms - this.booked;
  }; 
}
✶ 物件建構函式名稱通常第一個字母使用大寫
Hotel 函式有三個參數:name,rooms, 與 booked
✶ 在 Hotel 函式內建立各個物件特性及方法,每個指令的結束是分號,不是逗號
✶ JavaScript 沒有一般物件導向語言的類別 (Class),但建構子函式的功能類似類別

▸ 利用建構子函式產生物件實例 (Instance),例如:

var chaoyangHotel = new Hotel('朝陽飯店', 40, 25);
var holidayInn = new Hotel('假期飯店', 120, 77);
✶ 每個物件需有不同的變數名稱,指令 new Hotel(...) 產生一個新的物件實例, 並透過參數傳遞來設定物件的特性值

∗ 練習:利用建構表示法產生許多物件,並以整合的方式顯示所有飯店資訊

▸ 建立 ch3/multiple-objects.html (類似 object-literal.html):

...
<div id=info>
  <h2>飯店房間</h2> 
  <p id="hotel1"></p>
  <p id="hotel2"></p>
  <br>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/multiple-objects.js"></script>
...
✶ 建立兩個 <div>id 分別為 hotel1hotel2

▸ 建立 ch3/js/multiple-objects.js

$(document).ready(function() {

  function Hotel(name, rooms, booked) {
    this.name = name;
    this.rooms = rooms;
    this.booked = booked;
    this.checkAvailability = function() {
      return this.rooms - this.booked;
    }; 
  }

  var chaoyangHotel = new Hotel('朝陽飯店', 40, 25);
  var holidayInn = new Hotel('假期飯店', 120, 77);

  var chaoyangDetails = chaoyangHotel.name + '房間:';
  chaoyangDetails += chaoyangHotel.checkAvailability();
  $('#hotel1').html(chaoyangDetails);

  var holidayDetails = holidayInn.name + '房間:';
  holidayDetails += holidayInn.checkAvailability();
  $('#hotel2').html(holidayDetails);

});
✶ 首先利用建構子函式定義物件範本,在其中建立物件的特性與方法
✶ 產生兩個物件實例: chaoyangHotelholidayInn, 並給予不同的參數值
✶ 設定兩個飯店的細節資訊為:飯店名稱 + 房間: + 空房數
✶ 設定 idhotel1 的 HTML 元素的文字內容為朝陽飯店細節
✶ 設定 idhotel2 的 HTML 元素的文字內容為假期飯店細節

∗ 新增、修改、與刪除物件特性

▸ 新增特性:使用點號表示法,例如在 hotel 物件裡新增 gym 特性:

hotel.gym = true;

▸ 修改特性值:利用點號表示法或方括號法,例如:

hotel.name = '假期飯店';
hotel['name'] = '假期飯店';

▸ 刪除特性:利用 delete,例如刪除 name 這個特性:

delete hotel.name;

∗ 練習:更改飯店的特性

▸ 建立 ch3/add-modify-remove-properties.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="info">
  <h2>飯店設備</h2>
  <div id="hotelName"></div>
  <div id="pool">泳池</div>
  <div id="gym">健身房</div>
  <br>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/add-modify-remove-properties.js"></script>
...
✶ 建立兩個 <div>id 分別為 poolgym

▸ 建立 ch3/js/add-modify-remove-properties.js

$(document).ready(function() {

  var hotel = {
    name: '朝陽飯店',
    rooms: 40,
    booked: 25,
  };

  hotel.pool = false;
  hotel.gym = true;
  delete hotel.booked;

  $('#hotelName').html(hotel.name);
  $('#pool').addClass(hotel.pool.toString());
  $('#gym').addClass(hotel.gym.toString());

});
✶ 首先利用字面表示法建立 hotel 物件
✶ 加入 gympool 兩項特性,均為 Boolean 資料型態
✶ 刪除 booked 特性
✶ 最後,將 idpoolgym 的元素都加上 CSS class (.toString() 將 Boolean 轉為字串)

∗ 小結:建立物件的方法

▸ 先建立空物件,然後加入特性與方法

字面表示法建構子表示法
var hotel = {};

hotel.name = '朝陽飯店';
hotel.rooms = 40;
hotel.booked = 25;
hotel.checkAvailability = function() {
  return this.rooms - this.booked;
}
var hotel = new Object();

hotel.name = '朝陽飯店';
hotel.rooms = 40;
hotel.booked = 25;
hotel.checkAvailability = function() {
  return this.rooms - this.booked;
}

▸ 建立物件時,一併建立特性與方法

字面表示法建構子表示法 (可提供建立多個物件)
var hotel = {
  name: '朝陽飯店',
  rooms: 40,
  booked: 25,
  checkAvailability: function() {
    return this.rooms - this.booked;
  },
}
function Hotel(name, rooms, booked) {
  this.name = name;
  this.rooms = rooms;
  this.booked = booked;
  this.checkAvailability = function() {
    return this.rooms - this.booked;
  };
}

var chaoyangHotel = new Hotel('朝陽飯店', 40, 25);

▸ 作業 2

(3) 內建物件

∗ JavaScript 的內建物件 (Built-in objects) 可分為三類:

▸ 瀏覽器物件模型 (Browser object model, BOM,如下圖):表示目前瀏覽器視窗或頁籤的物件,例如:

window.print()         // 列印網頁
window.screen.width    // 裝置的寬度
bom

▸ 文件物件模型 (Document object model):表示目前網頁元素的物件,例如:

window.document.getElementById('one')    // 擷取 id 為 one 的 HTML 元素
document.getElementById('one')           // 亦可省略 window
document.lastModified                    // 網頁最後修改時間

▸ 全域 JavaScript 物件 (Global JavaScript objects):JavaScript 本身的物件,例如:字串 (String)、數值 (Number)、布林 (Boolean)、日期 (Date)、數學 (Math)、陣列 (Array)、正規表示式 (Regex)等

∗ 瀏覽器物件模型

window 物件表示目前瀏覽器視窗或頁籤,在瀏覽器物件模型的最高層,並包含有關瀏覽器的其他物件

window 的特性

特性說明
window.innerHeight 視窗高度 (Pixel)
window.innerWidth 視窗寬度 (Pixel)
window.pageXOffset 文件水平捲動的的距離 (Pixel)
window.pageYOffset 文件垂直捲動的的距離 (Pixel)
window.screenX 瀏覽器視域左緣與螢幕左緣的距離 (像素)
window.screenY 瀏覽器視域上緣與螢幕上緣的距離 (像素)
window.location 目前網址
window.document 目前網頁
window.history 視窗歷史
window.history.length 視窗歷史裡的項目數量
window.screen 螢幕
window.screen.width 螢幕寬度
window.screen.height 螢幕高度

window 的方法

方法說明
window.alert() 跳出訊息框
window.open() 開新視窗或頁籤
window.print() 列印頁面

∗ 練習:顯示 window 物件的特性值

▸ 建立ch3/window-object.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="info"></div> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/window-object.js"></script>
...

▸ 建立 ch3/js/window-object.js

$(document).ready(function() {

  var msg = '<h2>瀏覽器視窗</h2><p>寬度:' + window.innerWidth + '</p>';
  msg += '<p>高度:' + window.innerHeight + '</p>';
  msg += '<h2>歷史</h2><p>項目:' + window.history.length + '</p>';
  msg += '<h2>螢幕</h2><p>寬度:' + window.screen.width + '</p>';
  msg += '<h2>螢幕</h2><p>高度:' + window.screen.height + '</p><br>';

  $('#info').html(msg);
  alert('目前網頁:' + window.location);

});
✶ 將 window 相關特性集成字串 msg ,然後顯示在 idinfo 的元素裡
alert():因為網頁預設的物件就是 window, 因此 window.alert() 可以簡寫

∗ 文件物件模型

document 物件表示目前網頁,在文件物件模型的最高層,包含有關網頁的其他物件

docuement 的特性

特性說明
document.title 目前文件的標題
document.lastModified 文件最後修改時間
document.URL 目前文件的網址
document.domain 目前文件的網域

document 的方法

方法說明
document.write() 在網頁寫資料
document.getElementById() 回覆具有某個 id 的 HTML 元素
document.querySelectorAll() 回覆符合 CSS 選擇器的元素
document.createElement() 建立元素
document.createTextNode() 建立文字節點

∗ 練習:顯示 document 物件的特性值

▸ 建立 ch3/document-object.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="footer"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/document-object.js"></script>
...

▸ 建立 ch3/js/document-object.js

$(document).ready(function() {

  var msg = '<p><b>網頁標題:</b>' + document.title + '<br>';
  msg += '<b>網址:</b>' + document.URL + '<br>';
  msg += '<b>最後修改:</b>' + document.lastModified + '</p>';

  $('#footer').html(msg);

});
✶ 將 document 相關特性集成字串 msg ,然後顯示在 idfooter 的元素裡

(4) JavaScript 的全域物件

∗ 字串物件 (String object)

var say = 'Home sweet home ';

▸ 字串的特性

特性說明範例結果
length 字串長度 say.length; 16

▸ 字串的方法

方法說明範例結果
toUpperCase() 改為大寫字母 say.toUpperCase(); 'HOME SWEET HOME '
toLowerCase() 改為小寫字母 say.toLowerCase(); 'home sweet home '
charAt() 回覆某個字元所在位置 say.charAt(12); 'o'
indexOf() 回覆字元 (串) 第一次出現的位置 say.indexOf('ee'); 7
split() 分解字串 say.split(' '); ['Home', 'sweet', 'home', '']
trim() 刪除字串開頭或字串結尾的空白 say.trim(); 'Home sweet home'
replace() 置換第一個搜尋到的字串
置換所有字串 (g: global)
say.replace('me', 'w');
say.replace(/me/g, 'w')
'How sweet home'
'How sweet how'

∗ 練習:顯示 string 物件的特性值

▸ 建立 ch3/string-object.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="info"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/string-object.js"></script>
...

▸ 建立 ch3/js/string-object.js

$(document).ready(function() {

  var say = 'Home sweet home ';
  var msg = '<h2>"' + say + '"</h2><h2>length</h2><p>' + say.length + '</p>';
  msg += '<h2>Uppercase</h2><p>' + say.toUpperCase() + '</p>';
  msg += '<h2>Lowercase</h2><p>' + say.toLowerCase() + '</p>';
  msg += '<h2>Character index: 12</h2><p>' + say.charAt(12) + '</p>';
  msg += '<h2>First ee</h2><p>' + say.indexOf ('ee') + '</p>';
  msg += '<h2>Replace</h2><p>' + say.replace('me', 'w') + '</p><br>';

  $('#info').html(msg);

});
✶ 將 string 相關特性集成字串 msg ,然後顯示在 idinfo 的元素裡

∗ 數值物件 (Number object)

▸ 數值的方法

var num = 123.456;
方法說明範例結果
isNaN() 是否不是數值 (NaN: Not a Nnumber) isNaN(num) false
toFixed() 四捨五入到某個小數位數 (回覆字串) num.toFixed(2); 123.46
toPrecision() 四捨五入到某個總位數 (回覆字串) num.toPrecision(1);
num.toPrecision(2);
1e+2
1.2e+2
toExponential() 轉為指數型態 (回覆字串) num.toExponential(); 1.23456e+2

▸ 數值名詞

✶ 整數 (Integer)
✶ 實數 (Real number):含整數與小數
✶ 浮點數 (Floating point number):是一個實數,利用小數點表示小數
✶ 科學記號 (Scientific notation):3,750,000,000 可表示為 3.75×109 或 3.75e+9

∗ 練習:顯示 number 物件的特性值

▸ 建立 ch3/number-object.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="info"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/number-object.js"></script>
...

▸ 建立 ch3/js/number-object.js

$(document).ready(function() {

  var originalNumber = 10.23456;

  var msg = '原始數字</h2><p>' + originalNumber + '</p>';
  msg += '3 位小數</h2><p>' + originalNumber.toFixed(3) + '</p>';
  msg += '3 位數</h2><p>' + originalNumber.toPrecision(3) + '</p>';

  $('#info').html(msg);

});
✶ 將 number 相關特性集成字串 msg ,然後顯示在 idinfo 的元素裡

∗ 數學物件 (Math object)

▸ 數學的特性

特性說明範例結果
Math.PI 圓周率 Math.PI; 3.14...

▸ 數學的方法

var num = 123.456;
方法說明範例結果
Math.round() 四捨五入 Math.round(num); 123
Math.sqrt() 平方根 Math.sqrt(num); 11.11...
Math.ceil() 天花板運算 Math.ceil(num); 124
Math.floor() 地板運算 Math.floor(num); 123
Math.random() 隨機數,範圍:[0, 1) Math.random(); ...
Math.cos(),
Math.sin(), ...
三角函數 (回覆弧度值) Math.cos(num); -0.5947...

∗ 練習:產生範圍在 [1, 10] 的隨機整數

▸ 建立 ch3/math-object.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="info"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/math-object.js"></script>
...

▸ 建立 ch3/js/math-object.js

$(document).ready(function() {

  var randomNum = Math.floor(Math.random()*10 + 1);

  $('#info').html('<h2>隨機數字</h2><p>' + randomNum + '</p><br>');

});
✶ 將 Math.random() 乘以 10 再加 1 ,範圍變成 [1, 11) ,地板運算結果範圍為 [1, 10] ,最後顯示在 idinfo 的元素裡

∗ 日期物件 (Date object)

▸ 使用日期物件需先利用日期建構子產生一個日期實例,例如:

var today = new Date();

▸ JavaScript 將日期存成一個數字:從 1970/1/1 午夜 (00:00:00 Coordinated Universal Time, UTC) 到目前所經歷的毫秒 (Millisecond) 數, 此時間系統稱為 Unix time

console.log(today);

▸ 日期時間來自於執行程式的電腦內部時間,時區不同會有不同的時間,電腦內部時間不準也會造成問題

▸ 建立另一個時間變數 (三種格式):

var dob = new Date(1996, 11, 26, 15, 45, 55);
var today = new Date('Dec 26, 1996 15:45:55');
var today = new Date(1996, 11, 26);

▸ 日期時間的方法

方法說明
getDate(), setDate() 回覆、設定一個月裡的某日 (1 ~ 31)
getDay() 回覆某日是星期幾 (0 ~ 6:星期日 ~ 六)
getFullYear(), setFullYear() 回覆、設定西元年 (4 個數字)
getHours(), setHours() 回覆、設定小時 (0 ~ 23)
getMilliseconds(), setMilliseconds() 回覆、設定毫秒 (0 ~ 999)
getMinutes(), setMinutes() 回覆、設定分鐘 (0 ~ 59)
getMonth(), setMonth() 回覆、設定月份 (0 ~ 11)
getSeconds(), setSeconds() 回覆、設定秒 (0 ~ 59)
getTime(), setTime() 回覆、設定秒 (自 1970/1/1 午夜到所設定時間的總毫秒數)
getTimezoneoffset() 回覆時區的時差 (單位:分鐘)
toDateString() 回覆較適合人類閱讀的日期字串
toTimeString() 回覆較適合人類閱讀的時間字串
toString() 將日期時間轉為字串

▸ 比較日期時間先後:直接使用比較運算子 ( > , < , >= , <= )

▸ 比較日期時間是否相等:使用 .getTime() ,例如:

var same = date1.getTime() === date2.getTime();
var notSame = date1.getTime() !== date2.getTime();

∗ 練習:顯示 Date 物件的特性值

▸ 建立 ch3/date-object.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="footer"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/date-object.js"></script>
...

▸ 建立 ch3/js/date-object.js

$(document).ready(function() {

  var today = new Date();
  var year = today.getFullYear();

  $('#footer').html('<p>Copyright &copy;' + year + '</p>');

});
✶ 產生日期實例 today ,取出 4 位數的西元年並顯示在 idfooter 的元素裡

∗ 練習:計算時間差

▸ 建立 ch3/date-year-difference.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="message"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/date-year-difference.js"></script>
...

▸ 建立 ch3/js/date-year-difference.js

$(document).ready(function() {

  var today = new Date();
  var year = today.getFullYear();
  var start = new Date('Apr 16, 1996 15:45:55');
  var difference = today.getTime() - start.getTime();
  difference /= 31556900000;

  $('#message').html(Math.floor(difference) + ' 年來的線上旅遊諮詢');

});
✶ 產生日期實例 today ,取出 4 位數的西元年
✶ 設定一個時間:1996/4/16 (公司成立時間)
✶ 以毫秒來計算時間差,再除以一年的毫秒數算出總共幾年,最後取地板整數並顯示在 idmessage 的元素裡

▸ 建立 ch3/date-add-month.html (類似 object-literal.html):

...
<body>
<h1></h1>
<div id="message"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/date-add-month.js"></script>
...

▸ 建立 ch3/js/date-add-month.js

$(document).ready(function() {

  var nextMonth = new Date();  
  nextMonth.setMonth(nextMonth.getMonth()+1);
  var offerEnds = '優惠截止日:' + 
                  nextMonth.getFullYear() + '-' + 
                  nextMonth.getMonth() + '-' +
                  nextMonth.getDate();
  $('#message').html(offerEnds);

});
✶ 產生日期實例 nextMonth,再加上 1 個月 (Date 物件方法會正確處理月份資料)
✶ 最後設定日期格式並顯示

(5) jQuery 物件

∗ jQuery 物件

▸ 可將 JavaScript 的瀏覽器或文件物件加上 $(...) ,即可使用 jQuery 所提供的方法,例如:

$(window).width()      // 瀏覽器視域的寬度
$(document).ready()    // 文件載入完畢

▸ 將 CSS 選擇器 (Selector) 傳給 $() 即可產生 jQuery 物件,例如:

$('#someId')       // 選擇頁面有 id="someId" 的元素 (0 或 1 個)
$('.someClass')    // 選擇頁面有 class="someClass" 的元素 (0 或多個)

▸ 作業 3