基礎型別與語法
資料型別(Data Types)
-
基礎型別(Primitives)
-
boolean
布林型別(
trueorfalse) -
number
數字型別,使用 64 位元雙精度浮點數(double-precision 64-bit floating point) 格式存儲
-
string
字串型別(sequence of characters)
-
bigint
整數型別,可為任意大小
-
symbol2
符號型別,唯一且不可變的識別符(unique and immutable identifier)
-
null
空或無效型別(nonexistent or invalid object)
-
undefined
未定義型別,會自動賦予給未賦值的變數(unassigned variables)
-
函式型別(Function)
函式(Functions) 在技術上來說是一種 可被呼叫的物件(Callable Objects)
- 物件型別(Object)
詳見 類別與物件
語法(Syntax)
介紹(Introduction)
- 指令(instructions) 在 JavaScript 中被稱為 陳述式(statements) 並以 分號(
;) 分隔不同陳述式 - 如果在一行中僅有一個陳述式,則陳述式後面可以不加上分號(
;) - 一個陳述式可以跨越多行
- JavaScript 是 大小寫有別的(Case-sensitive) 且使用 Unicode 字元集來編碼
關鍵字(Keywords)
| Typescript | ||||||
|---|---|---|---|---|---|---|
| abstract1 | await2 | boolean1 | break | case | catch | void |
| class2 | const2 | continue | debugger | default | delete | do |
| else | enum2 | eval | export2 | extends2 | false | var |
| finally | for | function | goto1 | if | implements | import2 |
| in | instanceof | interface | let2 | new | while | typeof |
| null | private | protected | public | return | static | try |
| super2 | switch | this | throw | true | with | yield |
註解(Comments)
數值(Values)
- 不用 容器(container) 來參照數值的被稱為 字符(Literals)
- 使用 容器(container) 來參照數值的被稱為 變數(Variables)
字面值(Literals)
- 布林字面值(Boolean literals)
- 整數字面值(Numerical literals)
60; // 十進制
0b111100; // 二進制
0o74; // 八進制
0x3c; // 十六進制(a~f 不區分大小寫)
999999999999999999999999999999999999999n; // BigInt
- 浮點數字面值(Floating-point literals)
- 字串字面值(String literals)
- 陣列字面值(Array literals)
- 物件字面值(Object literals)
- 正則表達式字面值(RegExp literals)
- 樣板字面值(Template literals)2
// 基本字串
`In JavaScript '\n' is a line-feed.` // 多行字串
`My Love in her attire doth show her wit,
It doth so well become her;
For every season she hath dressings fit,
For Winter, Spring, and Summer.
No beauty she doth miss
When all her robes are on:
But Beauty’s self she is
When all her robes are gone.`;
// 字串插值 ${ expr }
const name = "Cindy";
const age = 18;
`${name} is ${age} year-old.`; // "Cindy is 18 year-old."
變數(Variables)
-
命名規則(Naming conventions)
-
不能與 關鍵字(Keywords) 同名
- 命名上可使用 字母(
a~z,A~Z) 、 底線(_) 、 美元符號($) 或 絕大多數的 Unicode 字母(e.g.å,è,ü) 作為開頭字元 - 命名上除了開頭可用字元外還可使用 數字(
0~9) 作為後續字元 -
在命名變數上建議表明其變數所具備的意義或用處,且在 JavaScript 中習慣使用 小駝峰命名法(lower camel case) 來命名變數(e.g.
flyingDistance,eventCounter,animalAge) -
宣告方式(Declaring ways)
-
var用於在函式內宣告 函式範圍變數(function-scoped variables) 或是在函式外宣告 全域範圍變數(globally-scoped variables) let2 用於宣告 區塊範圍變數(block-scoped local variables)-
const2 用於宣告 區塊範圍常數(read-only block-scoped local variables) -
宣告語法(Declaring syntax)
var|let|constvariableName=expression
運算子(Operators)
- 賦值運算子(Assignment operators)
- 賦值(Assignment)
= - 加法賦值或串接賦值(Addition assignment or Concatenation assignment)
+= - 減法賦值(Subtraction assignment)
-= - 乘法賦值(Multiplication assignment)
*= - 除法賦值(Division assignment)
/= - 餘數賦值(Remainder assignment)
%= - 指數賦值(Exponentiation assignment)
**= - 左移賦值(Left shift assignment)
<<= - 右移賦值(Right shift assignment)
>>= - 無號右移賦值(Unsigned right shift assignment)
>>>= - 位元 AND 賦值(Bitwise AND assignment)
&= - 位元 XOR 賦值(Bitwise XOR assignment)
^= - 位元 OR 賦值(Bitwise OR assignment)
|= - 邏輯 AND 賦值(Logical AND assignment)
&&= - 邏輯 OR 賦值(Logical OR assignment)
||= - 空值合併賦值(Nullish coalescing assignment)
??= - 比較運算子(Comparison operators)
- 等於(Equal)
==
運算元等價時回傳true,否則回傳 `false - 不等於(Not equal)
!=
運算元不等價時回傳true,否則回傳false - 嚴格等於(Strict equal)
===
運算元等價且型別相同時回傳true,否則回傳false - 嚴格不等於(Strict not equal)
!==
運算元不等價或型別不相同時回傳true,否則回傳false - 大於(Greater than)
>
左方運算元大於右方運算元時回傳true,否則回傳false - 大於或等於(Greater than or equal)
>=
左方運算元大於或等於右方運算元時回傳true,否則回傳 `false - 小於(Less than)
<
左方運算元小於右方運算元時回傳true,否則回傳false - 小於或等於(Less than or equal)
<=
左方運算元小於或等於右方運算元時回傳true,否則回傳false - 算術運算子(Arithmetic operators)
- 加法(Addition)
+ - 減法(Subtraction)
- - 乘法(Multiplication)
* - 除法(Division)
/ - 餘數(Remainder)
% - 指數(Exponentiation)
** - 遞增(Increment)
++ - 遞減(Decrement)
-- - 一元負號(Unary negation)
- - 位元運算子(Bitwise operators)
- 位元 AND(Bitwise AND)
& - 位元 OR(Bitwise OR)
| - 位元 XOR(Bitwise XOR)
^ - 位元 NOT(Bitwise NOT)
~ - 左移(Left shift)
<< - 右移(Sign-propagating right shift)
>> - 無號右移(Zero-fill right shift)
>>> - 邏輯運算子(Logical operators)
- 邏輯 AND(Logical AND)
&& - 邏輯 OR(Logical OR)
|| - 邏輯 NOT(Logical NOT)
! - 空值合併(Nullish coalescing)
?? - 字串運算子(String operators)
- 串接(Concatenation)
+ - 條件運算子(Conditional operator)
?:
- 逗點運算子(Comma operator)
,
- 一元運算子(Unary operators)
- delete
- typeof
- void
- 關係運算子(Relational operators)
- in
- instanceof
函式(Functions)
-
定義函式(Defining functions)
-
一個函式由下列元件組成
- 函式名稱
- 包圍在小括號(
())中,並由逗號(,)區隔的函式參數列表 - 包圍在大括號(
{})中,定義函式功能的 陳述式(statements)
- 呼叫函式(Calling functions)
function calcHypotenuse(leg1, leg2) {
return Math.sqrt(leg1 * leg1 + leg2 * leg2);
}
console.log(calcHypotenuse(3, 4)); // 5
表達式(Expressions)
- 表達式由 數值(values) 和 運算子(operators) 組合而成,並回傳 計算結果(evaluation)
宣告式(Declarations)
-
宣告變數(Declaring variables)
-
var宣告函式範圍或全域範圍變數
// 宣告全域範圍變數
var globalScope = 5;
function func() {
if (true) {
// 宣告函式範圍變數
var funcScope = 8;
console.log(globalScope); // 5
++globalScope;
console.log(funcScope); // 8
++funcScope;
}
console.log(globalScope); // 6
console.log(funcScope); // 9
}
func();
console.log(globalScope); // 6
console.log(funcScope); // ReferenceError: funcScope is not defined
let宣告區塊範圍變數
function func() {
if (true) {
// 宣告區塊範圍變數
let blockScope = 5;
console.log(blockScope); // 5
++blockScope;
}
console.log(blockScope); // ReferenceError: blockScope is not defined
}
func();
console.log(blockScope); // ReferenceError: blockScope is not defined
const宣告區塊範圍常數
function func() {
if (true) {
// 宣告區塊範圍常數
const readOnlyBlockScope = 5;
console.log(readOnlyBlockScope); // 5
++readOnlyBlockScope; // TypeError: Assignment to constant variable
}
console.log(readOnlyBlockScope); // ReferenceError: readOnlyBlockScope is not defined
}
func();
console.log(readOnlyBlockScope); // ReferenceError: readOnlyBlockScope is not defined
-
宣告函式與類別(Declaring functions and classes)
-
function宣告 函式(Functions)
function calcHypotenuse(leg1, leg2) {
return Math.sqrt(leg1 * leg1 + leg2 * leg2);
}
console.log(calcHypotenuse(3, 4)); // 5
function*宣告生成器函式,與yield結合能簡單編寫迭代器,我們會在這邊詳細介紹生成器。
function* generator(upperBound) {
for (let i = 0; i <= upperBound; ++i) {
yield i;
}
}
for (const i of generator(5)) {
console.log(i); // 0 -> 1 -> 2 -> 3 -> 4 -> 5
}
async function宣告非同步函式,我們會在這邊詳細介紹非同步函式。
async function awaitFunc() {
return await 5;
}
(async () => {
console.log(await awaitFunc()); // 5
})();
async function*宣告非同步生成器函式,與yield結合能簡單編寫迭代器
async function* awaitIterFunc() {
yield await 5;
yield await 7;
yield await 9;
}
(async () => {
for await (const num of asyncIterfunc()) {
console.log(num); // 5 -> 7 -> 9
}
})();
class宣告類別
class Person {
// Static Method
static introStr(name, age) {
return "Hello! My name is " + name + ". I'm " + age + " years old.";
}
// Constructor
constructor(height, weight) {
this.height = height;
this.weight = weight;
}
// Getter
get bmi() {
return this.calcBmi();
}
// Method
calcBmi() {
return this.weight / ((this.height * this.height) / 10000);
}
}
陳述式(Statements)
-
控制流程(Control flow)
-
if...else根據條件執行的語句區塊
switch在不同條件下執行的語句區塊
const job = "Software engineer";
switch (job) {
case "Software engineer":
console.log("Coding");
break;
case "Police":
console.log("Patrol");
break;
case "Doctor":
console.log("Surgery");
break;
default:
console.log("Unemployed");
}
return指定函式回傳值並退出函式
break中斷當前 loop 、 switch 或 label 的陳述式並將程式控制權轉移到被終止陳述式後的陳述式
continue中斷執行當前(或標記 *optional) loop 中該次所迭代的陳述式,並繼續執行 loop 中的下次迭代
let times = 5;
for (let i = 0; i < times; ++i) {
if (i == 3) {
continue;
}
console.log(i); // 0 -> 1 -> 2 -> 4
}
throw拋出使用者所定義的例外狀況
try...catch指定例外狀況捕捉範圍與回應的語句區塊
function errorFunc() {
throw new Error("I'm Error");
}
try {
// tryStatements
errorFunc();
} catch (exception) {
// catchStatements
console.error(exception);
} finally {
// finallyStatements
console.log("End of run.");
}
// catch 的參數可省略、 finally 區塊亦可省略
try {
// tryStatements
} catch {
// catchStatements
}
-
迭代(Iterations)
-
for由三個可選表達式組成的迴圈
/*
initialization: 在迴圈開始之前計算一次的表達式(含賦值表達式)或變數宣告式
condition: 每次迴圈迭代前要計算的表達式。若為true則執行該次迭代,否則中斷迴圈
afterthought: 在迴圈迭代結束時計算的表達式
*/
// for (initialization; condition; afterthought)
for (let i = 0; i < 5; ++i) {
console.log(i); // 0 -> 1 -> 2 -> 3 -> 4
}
while由條件判斷的迴圈
let i = 0;
/*
condition: 每次迴圈迭代前要計算的表達式。若為true則執行該次迭代,否則中斷迴圈
*/
// while (condition)
while (i < 5) {
console.log(i); // 0 -> 1 -> 2 -> 3 -> 4
++i;
}
for...in以任意順序迭代物件的可枚舉屬性(enumerable properties)
const object = { name: "Cindy", age: 31 };
for (const property in object) {
console.log(`${property}: ${object[property]}`); // name: Cindy -> age: 31
}
for...of迭代可迭代物件(包括陣列、類 別數組物件、迭代器和生成器)
for await...of迭代非同步可迭代物件
async function* asyncIterfunc() {
yield 5;
yield 7;
yield 9;
}
(async () => {
for await (const num of asyncIterfunc()) {
console.log(num); // 5 -> 7 -> 9
}
})();
do...while由條件判斷的迴圈,至少執行一次
提升(Hoisting)
- 讓變數和函數的 宣告 在編譯階段就被放入記憶體,但初始化的實際位置和程式碼中完全一樣
// 因為 calcHypotenuse 在編譯階段被 Hoisting,所以能被正常執行而不報錯
console.log(calcHypotenuse(3, 4)); // 5
function calcHypotenuse(leg1, leg2) {
return Math.sqrt(leg1 * leg1 + leg2 * leg2);
}