JavaScript入門

Date: Sep. 15th, 2019

Lecturer: Chia

目次

  • 什麼是 JavaScript?
  • 值、型別與運算子
  • 程式結構
  • 函式

什麼是 JavaScript?

  • JavaScript 是瀏覽器唯一指定的內建程式語言。
  • JavaScript 跟 Java 毫無關係

JavaScript 歷史

  • 隨之,Netscape 以外的瀏覽器也漸漸採用。
  • 1997年,建立 ECMAScript standard。
  • 1995年,JavaScript誕生,由 Netscape 著手開發一門在瀏覽器上執行的語言系統。

JavaScript 版本

版本 正式名稱 備註
1 ECMAScript 1 (1997) First Edition.
3 ECMAScript 3 (1999) 廣泛支援 (2000 - 2010)
5 ECMAScript 5 (2009) JS ES5
6 ECMAScript 2015 JS ES6
8 ECMAScript 2017 添加 Object
9 ECMAScript 2018 最新版

值、型別與運算子

  1. 數字 (Number)
  2. 字串(String)
  3. 布林值 (Boolean value)
  4. 空值 (Empty values)
  • 自動轉換型別

值、型別與運算子

  • JavaScript 是個「弱型別」的語言。
    • 變數沒有型別,值(value)才有

因此,變數本身無需宣告型別!

值、型別與運算子

  • 基本型別 (Primitives)
    1. Number
    2. String

    3. Boolean

    4. Null

    5. Undefined

JS ES5 標準,JavaScript 內建型別:

  • 物件型別 (Object)
    • function

數字 (Number)

  • JavaScript 只有一種數值的型別,就是 number。
  • 包含:整數、帶有小數點的數字、科學記號表示
var x = 3.14;
var x = 123e5;
var y = 123e-5;

數字 (Number)

console.log(typeof NaN);	//number
NaN === NaN;			// false
  • 除了常見的數字外,還有 3 種特殊的數字
    • Infinity:正無限大
    • -Infinity:負無限大
    • NaN:不是數值 (not a number)
      • NaN 並不等於任何的數字,甚至是自己。

數字 (Number)

  • 運算子

    • +   -   *   /   %

  • 運算順序

    • 有括號(),先運算
    • 先乘除或取餘數,後加減

字串(String)

console.log("Lie on the ocean");
console.log('Float on the ocean');
console.log(`Down on the sea`);

console.log('這不是一行文 \
            這是第二行');
  • JavaScript沒有char(字元)的概念,只有字串。
  • 使用" "、' '或 ` `,將字串包起來。
  • 運算子
    • +
console.log("con" + "cat" + "e" + "nate");

字串(String)

console.log(`half of 100 is ${100 / 2}`);
  • 樣板字面值(Template literal)
    • 外部:必須由 ` ` 包裹。

    • 內部:由 $ 及 { } 構成佔位符 ( ${expression} ),允許字串嵌入運算式並返回運算結果。

布林值 (Boolean value)

console.log(3 > 2);
console.log("a" < "Z");
  • 比較運算子
    • >        <      >=      <=
    • ==     !=
      • 將型別一致化後比較。
    • ===      !==
      • 不會將型別一致化後比較。
      • 若型別不同,直接回傳 fasle。
  • 布林值的值只有兩種:true 和 false,通常用於判斷式,作為控制程式流程的用途。

布林值 (Boolean value)

console.log(true && false);
console.log(false || true);
console.log(!false);
  • 邏輯運算子
    • && (and)
    • || (or)
    • ! (not)

空值 (Empty values)

console.log(typeof undefined);
Boolean(undefined)	//false

console.log(typeof null);
Boolean(null) 		//false
  1. undefined (未定義)
    • 代表「(此變數) 尚未給值,所以不知道是什麼」。
    • 資料型別為 undefined。
  2. null (沒有值)
    • 代表「(此變數可能曾經有值,可能沒有值) 現在沒有值」。
    • 資料型別為 object。

空值 (Empty values)

var a;          
console.log(typeof a);   //undefined

var a = "";
console.log(typeof a);   //string
  • undefined (未定義)
  • null (沒有值)
var b = null;
console.log(typeof b);   //object
  • 當運算元的型別不同時,JavaScript 會自動依規則 type coercion (強制轉型)並運算

自動轉換型別

console.log(8 * null); //null => 0
console.log("5" - 1);  //5 (from string to number)
console.log("5" + 1);  //1 (from number to string)

console.log("five" * 2);
// → NaN
console.log(false == 0 && "" == false);
// → true
console.log(null == 0);
// → false
  • Three-character comparison operators
    • ===:嚴格相等
    • !==:嚴格不相等
  • 先比較型別,再比大小
    • 避免 JavaScript 強制轉換型別

自動轉換型別

console.log(null == undefined);   
//true
console.log(null === undefined);  
//false (型別不同,直接回傳 fasle)

程式結構

  • 運算式與敘述句
  • 變數宣告
  • 變數名稱的命名
  • 註解
  • 流程控制

運算式與敘述句

  • Expression (運算式)
    • 產生值(value)的不完整程式碼片段。
    • Ex: !false、"SIRLA"、-( 2+3 )
  • Statement (敘述句)
    • 一段完整的程式碼,執行某個動作。
    • Ex: console.log( -( 2+3 ) );
  • JavaScript是以 ; 來判斷一段程式碼的結束。
  • 有無縮排,在JavaScript並不影響。

變數宣告

let a = 5 * 5;
console.log(a);            // → 25
  • 用於宣告變數的保留字(keyword)
    • let
      • 宣告區域變數。
let mood = "light";
mood = "dark";
console.log(mood);    	   // → dark

變數宣告

const greeting = "Hello "; 
greeting = "a"; 
console.log(greeting);	//Error
  • 用於宣告變數的保留字(keyword)
    • var (short for “variable”)
      • ES5 的遺物,應避免使用var。
      • 宣告全域變數。
    • const (constant)
      • 宣告常數,不能再作修改。

      • 宣告區域變數。

var name = "Ayda";
const greeting = "Hello ";
console.log(greeting + name);    // → Hello Ayda

變數名稱的命名

break case catch class const continue debugger default
delete do else enum export extends false finally for
function if implements import interface in instanceof let
new package private protected public return static super
switch this throw true try typeof var void while with yield
  • 可以是任何字母、數字,但開頭不可為數字。
    • 駝峰式命名:FuzzyLittleTurtle、fuzzyLittleTurtle。
    • JavaScript 區分大小寫。

  • 可以包含$_,但不可有其他標點符號、特殊字元或空白(space)。
    • Ex:fuzzy_little_turtle
  • 不可為保留字 (keywords)。

註解

  • 單行註解://
  • 多行註解:/* */

流程控制

  • 直線型的流程
  • 條件型的流程
    • if
    • if ... else ...
    • if ... else if ... else ...
  • 迴圈型(loop)的流程
    • while
    • do ... while
    • for
  • 分派型(dispatch)的流程
    • switch

直線型的流程

let Num = Number(prompt("輸入數字:"));
console.log("平方後的結果:" + Num * Num);

條件型的流程

  • if
let Num = Number(prompt("輸入數字:"));

if (!Number.isNaN(Num)) {
  console.log("平方後的結果:" + Num * Num);
}
if (1 + 1 == 2) console.log("It's true");
// → It's true

條件型的流程

  • if ... else ...
let Num = Number(prompt("輸入數字:"));

if (!Number.isNaN(Num)) {
  console.log("平方後的結果:" + Num * Num);
} else {
  console.log("Hey. Why didn't you give me a number?");
}

條件型的流程

  • if ... else if ... else ...
let Num = Number(prompt("輸入數字:"));

if (Num < 10) {
  console.log("Small");
} else if (Num < 100) {
  console.log("Medium");
} else {
  console.log("Large");
}

迴圈型(loop)的流程

  • while
let number = 0;
while (number < 8) {
  console.log(number);
  number = number + 2;
}
  • do ... while
let yourName;
do {
  yourName = prompt("Who are you?");
} while (!yourName);
console.log(yourName);

迴圈型(loop)的流程

  • for
for (let num = 0; num < 7; num = num + 2) {
  console.log(num);
}
// → 0, 2, 4, 6
let result = 1;
for (let counter = 0; counter < 10; counter++) {
  result = result * 2;
}
console.log(result);        
// → 1024

迴圈型(loop)的流程

  • break:跳出迴圈。
for (let current = 20; current < 30; current ++) {
  if (current % 2 == 0) {
    continue;
  } 
  console.log(current);
}
// → 21, 23, 25, 27, 29
for (let current = 20; ; current ++) {
  if (current % 7 == 0) {
    console.log(current);    break;
  }
}
// → 21
  • continue:跳出loop body,但仍在迴圈內繼續跑。

LAB 01 - FizzBuzz

  • Uses console.log to print all the numbers from 1 to 100, with three exceptions.

    • numbers / 3   =>  print "Fizz"

    • numbers / 5 (and not 3)   =>  print "Buzz"

    • numbers / 15   =>  print "FizzBuzz"

    • else    =>  print  numbers

LAB 01 - FizzBuzz

for (let n = 1; n <= 100; n++) {
  let output = "";
  if (n % 3 == 0) {
    output += "Fizz";
  }  
  if (n % 5 == 0) {
    output += "Buzz";
  }
  console.log(output || n);
}

分派型(dispatch)的流程

  • switch
    • 若case敘述內缺少break,switch將持續執行至含有break的case才停止。
switch (prompt("What is the weather like?")) {
  case "rainy":
    console.log("Remember to bring an umbrella.");
    break;
    
  case "sunny":
    console.log("Dress lightly.");
    
  case "cloudy":
    console.log("Go outside.");
    break;
    
  default:
    console.log("Unknown weather type!");
    break;
}

函式

  • 定義與呼叫函式
  • 全域與區域
  • 閉包(Closure)
  • 遞迴

函式

  • 物件(Object)的一種。
  • 一個函式會包含三個部分:
    1. 函式的名稱 (也可能沒有名稱)

    2. ( ) 中的部分為「參數」。多個參數,用 , 隔開。

    3. { } 內的部分,放需要重複執行的運算。

function square(number) {
  return number * number;
}
square(2);        // 4

定義與呼叫函式

  • 定義函式 (3種方式)
    1. 函式宣告
    2. 函式運算式
    3. 箭頭函式
function 名稱([參數]) {
  ...
}   
function square(x) {
  return x * x;
}
//匿名函式
變數名稱 = function ([參數]) {
  ...
}
const makeNoise = function() {
  console.log("Pling!");
};
makeNoise();	// → Pling!

console.log(typeof makeNoise);	//function
//當箭頭函式無參數時,()仍保留。
變數名稱 = ([參數]) => {
  ...
};
const power = (base, exponent) => {
  let result = 1;
  for (let count = 0; count < exponent; count++) {
    result *= base;
  }
  return result;
};

LAB 02 - Minimum

  • Write a function min that takes two arguments and returns their minimum.

    • 使用 3 種定義函式的方式,分別寫出 min 函式。

// Your code here.

console.log(min(0, 10));
// → 0
console.log(min(0, -10));
// → -10

LAB 02 - Minimum

function min(a, b) {
  if (a < b){
    return a;
  }else{
    return b;
  }
}

console.log(min(0, 10));
// → 0
console.log(min(0, -10));
// → -10
  • 定義函式 (3種方式)
    1. 函式宣告
    2. 函式運算式
    3. 箭頭函式
const min = function(a, b) {
  if (a < b){
    return a;
  }else{
    return b;
  }
};

console.log(min(0, 10));
// → 0
console.log(min(0, -10));
// → -10
let min = (a, b) => {
  if (a < b){
    return a;
  }else{
    return b;
  }
}

console.log(min(0, 10));
// → 0
console.log(min(0, -10));
// → -10

定義與呼叫函式

  • 呼叫函式
    • 放在函式定義的前面或後面。
    • 因為JavaScript在編譯階段,自動將變數和函式定義先放入記憶體,再去執行函式呼叫。
名稱([參數]);
const square = function(x) {
  return x * x;
};
square(3); //9

全域與區域

  • 變數作用的範圍
    1. 全域 (global):可在整份程式碼的任何地方使用。
      • 全域變數:var
    2. 區域 (local):只可在函式區塊內使用。
      • 區域變數:let、const
let x = 10;    //這裡的x為global
if (true) {
  let y = 20;    
  var z = 30;    
  console.log(x + y + z);      // → 60
}
// y is not visible here
console.log(x + z);            // → 40

閉包(Closure)

  • 不使用閉包(closure)的情況
// 狗的計數函式
var count = 0;
function countDogs () {
  count += 1;
  console.log(count + ' dog(s)');
};

// 貓的計數函式
var count = 0;
function countCats () {
  count += 1;
  console.log(count + ' cat(s)');
};

countCats();
countCats();
countDogs();
countDogs();
countDogs();
countCats();

閉包(Closure)

  • 利用閉包(closure)的作法,讓函式有自己私有變數
// 狗的計數程式
function dogHouse () {
  var count = 0;
  function countDogs () {
    count += 1;
    console.log(count + ' dog(s)');
  }
  return countDogs;
};
const a = dogHouse();

// 貓的計數函式
function catHouse () {
  var count = 0;
  function countCats () {
    count += 1;
    console.log(count + ' cat(s)');
  }
  return countCats;
};
const b = catHouse();

b();    // 1 cat(s)
b();    // 2 cat(s)
a();    // 1 dog(s)
a();    // 2 dog(s)
a();    // 3 dog(s)
b();    // 3 cat(s)

閉包(Closure)

  • 利用閉包(closure)的作法,讓函式有自己私有變數
    • 進一步簡化程式直接 return function
// 狗的計數程式
function dogHouse () {
  var count = 0;
  return function () {
    count += 1;
    console.log(count + ' dog(s)');
  }
};
const countDogs = dogHouse();

// 貓的計數函式
function catHouse () {
  var count = 0;
  return function () {
    count += 1;
    console.log(count + ' cat(s)');
  }
};
const countCats = catHouse();

countCats();    // 1 cat(s)
countCats();    // 2 cat(s)
countDogs();    // 1 dog(s)
countDogs();    // 2 dog(s)
countDogs();    // 3 dog(s)
countCats();    // 3 cat(s)

閉包(Closure)

  • 利用閉包(closure)的作法,讓函式有自己私有變數
    • 甚至運用同一個 dogHouse時,變數間也都是獨立的執行環境不會干擾。
function dogHouse () {
  var count = 0;
  function countDogs () {
    count += 1;
    console.log(count + ' dog(s)');
  }
  return countDogs;
};

var countGolden = dogHouse();
var countBlack = dogHouse();
var countPuppy = dogHouse();

countBlack();      // 1 dog(s)
countBlack();	  // 2 dog(s)

countPuppy();      // 1 dog(s)
countBlack();	  // 3 dog(s)

countGolden();     // 1 dog(s)
countPuppy();      // 2 dog(s)
countGolden();     // 2 dog(s)

遞迴

  • 函式內不斷呼叫自己本身。
  • 缺點:以遞迴的方式執行程式,其速度比迴圈慢三倍。

function power(base, exponent) {
  if (exponent == 0) {
    return 1;
  } else {
    return base * power(base, exponent - 1);
  }
};

console.log(power(2, 3));    // → 8

感謝聆聽

JavaScript入門

By BessyHuang

JavaScript入門

  • 434