JavaScript(縮寫 JS)是一種開發人員用來建立互動式網頁的程式設計語言,可以提升使用者體驗,這篇文章是我學習 JavaScript 的筆記內容。
1. JavaScript 入門
1.1 JavaScript 簡介
JavaScript(縮寫 JS)是一門基於原型和頭等函式的多範式進階直譯程式語言,它支援物件導向程式設計、指令式編程和函數式程式設計。
【範例:印出 Hello World!】
打開.html文件,在<body>標籤內,新增<script>標籤,並在內輸入console.log("Hello World!");。
<script>console.log("Hello World!");</script>
開啟瀏覽器,進入開發人員工具,即可在 Console 頁面中看到輸出結果:Hello World!。
【註解】
單行註解:
// 註解
多行註解:
/*
註解
註解
*/
1.2 資料、資料型態
數字:
3;
3.14;
-3;
字串:
("hello!");
布林值:
true;
false;
空值:
null;
未定義:
undefined;
1.3 變數、常數
1.3.1 變數
輸出 undefined:
let x;
console.log(x);
輸出 10:
x = 10;
console.log(x);
輸出 true:
x = true;
console.log(x);
輸出 null:
x = null;
console.log(x);
輸出 hello:
let abc = "hello";
console.log(abc);
1.3.2 常數
輸出 100,且 x 不可變:
const x = 100;
console.log(x);
1.4 運算符號
1.4.1 算數運算
使用加減乘除做運算。
輸出 1:
let x = 7 % 3;
console.log(x);
- %:取餘數。
1.4.2 指定運算
指定一個值給變數。
輸出-2:
x = 1;
x += 1;
x -= 4;
console.log(x);
- =:將符號右邊的值賦予到左邊的變數中。
- +=:a = a + b。
- -=:a = a - b。
1.4.3 比較運算
透過布林邏輯得到 TRUE 或 FALSE。
輸出 true:
x = 4 == 4;
console.log(x);
- 等於:==
- 不等於:!=
- 完全等於:===
- 完全不等於:!==
1.4.4 單元運算
針對單一資料做運算。
輸出 4:
x = 3;
x++;
console.log(x);
- 變數加一:++
- 變數減一:–
- 布林值反運算:!
1.4.5 邏輯運算
針對布林值的運算,使用 And(&&)、Or(||)。
輸出 false:
let test = true && false;
console.log(test);
輸出 true:
let test1 = true || false;
console.log(test1);
1.4.6 乘法運用
彈出視窗讓使用者輸入數字,並將兩個數字相乘,印出結果:
let n1 = prompt("請輸入一個數字", "");
let n2 = prompt("請輸入二個數字", "");
let result = n1 * n2;
console.log(result);
1.5 流程控制:判斷式
if 判斷式:
let money = prompt("要領多少錢?", "請輸入數字");
if (money < 100) {
console.log("太少!");
} else if (money <= 100000) {
console.log("OK!");
} else {
console.log("NO!");
}
console.log("判斷式結束");
1.6 流程控制:迴圈
while 迴圈:
let n = 0;
while (n < 3) {
console.log(n);
n++;
}
let n = 1;
let result = 0;
while (n <= 10) {
result = result + n;
n++;
}
console.log(result);
for 迴圈:
for (let n = 0; n < 3; n++) {
console.log(n);
}
result = 0;
for (let n = 1; n <= 10; n++) {
result += n;
}
console.log(result);
1.7 流程控制:迴圈指令
break,強制結束整個迴圈:
let n = 0;
while (n < 5) {
if (n == 4) {
break;
}
console.log(n);
n++;
}
continue,跳過本次迴圈,但不會結束迴圈,會繼續下一圈:
for (let n = 0; n < 5; n++) {
if (n == 3) {
continue;
}
console.log(n);
}
1.8 JavaScript 函式基礎
印出 hello:
function test() {
console.log("hello");
}
test();
印出 world:
function show(message) {
console.log(message);
}
show("world");
1.9 函式回傳值
return 會終止函式執行,並指明函式呼叫器(function caller)要回傳的數值。
【範例 1】
function test() {
console.log("hello");
return "bbb";
}
let value = test();
console.log(value);
輸出結果:
hello
bbb
【範例 2】
function divide(n1, n2) {
let result = n1 / n2;
console.log(result);
return result;
}
let ans = divide(4, 2);
console.log(ans);
輸出結果:
2
2
1.10 物件基礎
【範例】
let man = new Object();
man.age = 18;
man.name = "小王";
man.talk = function () {
console.log("hello", this.name, this.age);
};
console.log(man);
console.log(man.age);
console.log(man.age > 20);
man.talk();
【範例:JSON】
let man = {
age: 15,
name: "小王",
talk: function () {
console.log("hello", this.name, this.age);
},
};
console.log(man);
man.talk();
1.11 陣列物件
【範例 1:利用 push,將數字推進去陣列】
let grades = [];
grades.push(70);
grades.push(50);
grades.push(90);
console.log(grades);
【範例 2:取得陣列中特定位置的數字】
let grades = [70, 50, 90];
grades.push(25);
grades.push(100);
console.log(grades);
console.log(grades[0]);
console.log(grades[1]);
console.log(grades[2]);
console.log(grades[3]);
console.log(grades[4]);
console.log(grades.length);
console.log(grades[grades.length - 1]);
輸出結果:
(5)[(70, 50, 90, 25, 100)]
70
50
90
25
100
5
100
【範例 3:用 for 取得陣列資料】
let grades = [70, 50, 90];
grades.push(25);
grades.push(100);
for (let i = 0; i < grades.length; i++) {
console.log(grades[i]);
}
輸出結果:
70
50
90
25
100
【範例 4:平均數,算總和】
let grades = [70, 50, 90];
grades.push(25);
grades.push(100);
let total = 0;
for (let i = 0; i < grades.length; i++) {
total = total + grades[i];
}
let avg = total / grades.length;
console.log(total);
console.log(avg);
輸出結果:
335
67
2. JavaScript 動態網頁開發
2.1 HTML DOM 觀念
HTML DOM:
console.log(window);
開啟瀏覽器,進入開發人員工具,即可在 Console 頁面中看到 window 物件。
視窗寬度高度:
console.log(window.innerWidth, window.innerHeight);
透過 screen 取得螢幕尺寸:
console.log(window.screen.width, window.screen.height);
取得網址列內容:
console.log(window.location.href);
更改網址列內容:
window.location.href = "https://www.google.com/";
document:
console.log(window.document);
console.dir(document);
取得網頁標題:
console.log(document.title);
更改網頁標題:
document.title = "新標題";
取得 body 標籤:
console.log(document.body);
更改網頁主畫面內容(body 內容):
console.log(document.body.innerHTML);
document.body.innerHTML = "hello!!!!!!";
2.2 HTML DOM 網頁畫面操作
【範例:按鈕與文字變化】
<h3>Hello!</h3>
<div id="content">練習網頁畫面操作</div>
<button onclick="change();">點我</button>
function change() {
// 取得標籤物件
let elem = document.querySelector("#content");
console.log(elem);
// 操作標籤物件
elem.innerHTML = "新操作";
elem.className = "text";
elem.style.fontSize = "30px";
elem.style.color = "red";
}
【範例:選單變化】
<div>
<span onclick="changeToAbout();">關於我</span>
<span onclick="changeToExps();">學經歷</span>
</div>
<hr />
<div id="about">大家好,我是XXX</div>
<div id="exps" style="display: none">我是XX工程師</div>
function changeToAbout() {
let aboutDiv = document.querySelector("#about");
let expsDiv = document.querySelector("#exps");
aboutDiv.style.display = "block";
expsDiv.style.display = "none";
}
function changeToExps() {
let aboutDiv = document.querySelector("#about");
let expsDiv = document.querySelector("#exps");
aboutDiv.style.display = "none";
expsDiv.style.display = "block";
}
2.3 事件處理
向指定元素添加事件,然後透過函式去控制該事件,例如點擊按鈕。
<style>:
.btn {
background-color: #ffcccc;
padding: 5px;
border-radius: 5px;
cursor: pointer;
}
<body>:
<button
onclick="console.log('點擊事件');"
onmouseover="console.log('滑鼠移入');"
onmouseout="console.log('滑鼠移出');"
onmousedown="console.log('滑鼠按住');"
onmouseup="console.log('滑鼠放開');"
>
點我
</button>
<span
class="btn"
onmouseover="over(this);"
onmouseout="out(this);"
onmousedown="down(this);"
onmouseup="up(this);"
>點我</span
>
<script>:
function over(elem) {
elem.style.backgroundColor = "#ddaaaa";
}
function out(elem) {
elem.style.backgroundColor = "#ffcccc";
}
function down(elem) {
elem.style.fontWeight = "bold";
}
function up(elem) {
elem.style.fontWeight = "normal";
}
2.4 HTTP 通訊協定簡介
- 超文字傳輸通訊協定 (HTTP) 是全球資訊網的基礎,用於透過超文字連結載入網頁。
- HTTP 流程:由客戶端(Client)發出請求(Request),伺服器端(Server)接收請求,再將回應(Response)傳送到客戶端。
- DNS 域名系統(Domain Name System):負責將域名轉換成 IP 位置。
2.5 AJAX 網路連線
【範例:將.json中的內容印出來】
<body>:
<button onclick="getData();">連線取得資料</button>
<div id="result"></div>
<script>:
function getData() {
fetch("https://cwpeng.github.io/live-records-samples/data/products.json")
.then(function (response) {
return response.json();
})
.then(function (data) {
let result = document.querySelector("#result");
result.innerHTML = "";
for (let i = 0; i < data.length; i++) {
let product = data[i];
result.innerHTML +=
"<div>" +
product.name +
", " +
product.price +
", " +
product.description +
"</div>";
}
});
}
3. JavaScript 深入進階
3.1 箭頭函式
【未使用箭頭函式】
function calculate(max) {
let result = 0;
let n = 1;
while (n <= max) {
result += n;
n++;
}
return result;
}
let ans1 = calculate(10);
let ans2 = calculate(20);
console.log(ans1, ans2);
【使用箭頭函式】
let calculate = (max) => {
let result = 0;
let n = 1;
while (n <= max) {
result += n;
n++;
}
return result;
};
let ans1 = calculate(10);
let ans2 = calculate(20);
console.log(ans1, ans2);
【更簡化的箭頭函式】
// let multiply = (n1, n2) => {
// return n1 * n2;
// };
let multiply = (n1, n2) => n1 * n2;
let ans = multiply(3, 4);
console.log(ans);
3.2 解構賦值
3.2.1 陣列解構賦值
【範例:解構前】
let arr = [3, 4, 5];
let d1 = arr[0];
let d2 = arr[1];
let d3 = arr[2];
console.log(d1, d2, d3);
印出結果:
3 4 5
【範例 1】
let arr = [3, 4, 5];
let [d1, d2, d3] = arr;
console.log(d1, d2, d3);
印出結果:
3 4 5
【範例 2】
let arr = [3, 4, 5];
let d1, d2, d3;
[d1, d2, d3] = arr;
console.log(d1, d2, d3);
印出結果:
3 4 5
【範例 3】
let arr = [3, 4, 5, 2];
let d1, d2, d3, d4;
[d1, d2, d3, d4 = 10] = arr;
console.log(d1, d2, d3, d4);
印出結果:
3 4 5 2
【範例:變數資料交換】
let n1 = 3;
let n2 = 4;
[n2, n1] = [n1, n2];
console.log(n1, n2);
印出結果:
4 3
3.2.2 物件解構賦值
【範例:解構前】
let obj = { x: 3, y: 4 };
let x = obj.x;
let y = obj.y;
console.log(x, y);
印出結果:
3 4
【範例 1】
let obj = { x: 3, y: 4 };
let { x, y } = obj;
console.log(x, y);
印出結果:
3 4
【範例 2】
let obj = { x: 3, y: 4, z: 5 };
let x, y, z;
({ x, y, z = 10 } = obj);
console.log(x, y, z);
印出結果:
3 4 5
【範例 3】
let obj = { x: 3, y: 4, z: 5 };
let newX, newY, newZ;
({ x: newX, y: newY, z: newZ = 10 } = obj);
console.log(newX, newY, newZ);
印出結果:
3 4 5
3.2.3 函式的物件參數
【範例:包到 args 物件裡面】
function add(args) {
console.log(args.n1 + args.n2);
}
add({ n1: 3, n2: 4 });
印出結果:
7
【範例:運用解構賦值】
function add({ n1, n2 }) {
console.log(n1 + n2);
}
add({ n1: 3, n2: 4 });
印出結果:
7
3.3 其餘運算
3.3.1 運用在解構賦值
【範例:陣列解構賦值】
let [n1, n2, ...data] = [3, 2, 1, 5, 4, 0];
console.log(n1, n2, data);
印出結果:
3 2 (4) [1, 5, 4, 0]
【範例:物件解構賦值】
let { x, y, ...data } = { x: 3, y: 4, z: 5, a: 1, b: 2 };
console.log(x, y, data);
印出結果:
3 4 {z: 5, a: 1, b: 2}
3.3.2 運用在函式參數
【範例】
function add(n1, n2, ...args) {
console.log(n1, n2, args);
let total = n1 + n2;
for (let i = 0; i < args.length; i++) {
total = total + args[i];
}
console.log(total);
}
add(3, 4);
add(5, 6, 1, 2);
add(1, 2, 3, 1, 1);
印出結果:
3 4 []
7
5 6 (2) [1, 2]
14
1 2 (3) [3, 1, 1]
8
3.4 模組
在<body>標籤內新增:
<script type="module" src="main.js"></script>
新增main.js文件,內容:
【範例 1】
import echo from "./lib.js";
let name = "hello";
echo(name);
【範例 2】
import echo from "./lib.js";
let name = "hello";
lib.echo("world");
lib.add(3, 4);
新增lib.js文件,內容:
【範例 1】
function echo(msg) {
console.log(msg);
}
export default echo;
【範例 2】
function echo(msg) {
console.log(msg);
}
function add(n1, n2) {
console.log(n1 + n2);
}
export default {
echo: echo,
add: add,
};
3.5 模組的輸出、輸入
main.js:
【範例:預設輸入】
import abc from "./lib.js";
console.log(abc);
【範例:非預設輸入】
import { data } from "./lib.js";
import abc, { data, obj } from "./lib.js";
console.log(data);
console.log(obj);
【範例:彈性】
import { multiply } from "./lib.js";
multiply(3, 4);
multiply(-2, 2);
import math from "./lib.js";
math.add(3, 4);
math.multiply(-3, 4);
lib.js:
【範例:預設輸出】
let x = "hello";
export default x;
【範例:非預設輸出】
let x = "hello";
let data = [5, 6, 7];
let obj = { x: 10, y: 2 };
// export { data, obj };
export { x as default, data, obj };
【範例:彈性】
let add = function (n1, n2) {
console.log(n1 + n2);
};
let multiply = function (n1, n2) {
console.log(n1 * n2);
};
let math = {
add: add,
multiply: multiply,
};
export default math;
export (add, multiply);
3.6 Proxy 代理物件
【範例】
let data = {
price: 100,
count: 5,
};
let proxy = new Proxy(data, {
get: function (target, property) {
// console.log("代理的目標物件", target);
// console.log("取得的屬性名稱", property);
// return "屬性對應的資料";
if (property === "total") {
return target.price * target.count;
} else {
return target[property];
}
},
});
// 使用代理物件,取得物件屬性資料
console.log("總價", proxy.total);
console.log("單價", proxy.price);
3.7 淺拷貝、深拷貝
3.7.1 淺拷貝
淺拷貝是拷貝到第一層。
【範例】
let a = [0, 1, { x: 2, y: 3 }]; // 兩層的物件結構
let b = [...a];
b[0] = 10;
console.log(a[0]); // 不會影響,印出0
b[2].x = 20;
console.log(a[2].x); // 會影響,印出20
從上述得知,由於淺拷貝的關係,不會影響到a[0]的印出結果;但第二層不會被拷貝,所以不會印出第二層中的2,而是印出20。
3.7.2 深拷貝
深拷貝是全部拷貝。
【範例】
let a = [0, 1, { x: 2, y: 3 }];
let str = JSON.stringify(a);
let b = JSON.parse(str);
b[2].x = 20;
console.log(a[2].x); // 不會影響,印出2