目錄
1. 作用域
(1) 局部作用域
(2) 全局作用域
2. 垃圾回收
(1) 引用計數法
(2) 標記清除法
3. 閉包
(1) 作用
(2) 風險
4. 變量提升
(1)?var
(2)?let?和?const
(3)?const
5. 函數提升
(1) 函數聲明
(2) 函數表達式
6. 函數參數
(1) 動態參數
(2) 剩余參數
(3) 展開運算符
7. 必須加分號的兩種情況
(1) 立即執行函數
(2) 使用數組的時候
8. 箭頭函數
(1) 特點
9. Symbol
10. 生成器函數
11. Promise
12.?async?和?await
(1)?async
(2)?await
1. 作用域
作用域是指變量和函數的可訪問范圍。
(1) 局部作用域
- 函數作用域:在函數內部聲明的變量,外部無法訪問。
javascript
function foo() {var x = 10; // 函數作用域 } console.log(x); // 報錯:x未定義
- 塊作用域:在大括號?
{}
?內部聲明的變量。var
?聲明的變量不會產生塊作用域。let
?和?const
?聲明的變量會產生塊作用域。
javascript
if (true) {let y = 20; // 塊作用域 } console.log(y); // 報錯:y未定義
(2) 全局作用域
- 最外層聲明的變量,在任何地方都可以訪問。
javascript
var z = 30; // 全局作用域 function bar() {console.log(z); // 30 }
2. 垃圾回收
垃圾回收是指自動管理內存的機制,釋放不再使用的內存。
(1) 引用計數法
- 已棄用。
- 通過記錄對象被引用的次數來判斷是否回收。
- 缺點:無法處理循環引用(兩個對象相互引用),導致內存泄漏。
(2) 標記清除法
- 從全局對象(根部)開始掃描,標記所有可達的對象。
- 未標記的對象會被回收。
- 解決了循環引用的問題。
3. 閉包
閉包是指一個函數及其對周圍狀態的引用捆綁在一起。
(1) 作用
- 外部訪問函數內部變量,實現數據私有。
javascript
function outer() {let count = 0;return function inner() {count++;return count;}; } const fn = outer(); console.log(fn()); // 1 console.log(fn()); // 2
(2) 風險
- 閉包會導致內存泄漏,因為內部函數會保留對外部函數變量的引用。
4. 變量提升
變量提升是指將變量聲明提升到當前作用域的最前面。
(1)?var
- 函數作用域。
- 變量提升。
- 可以重復聲明。
javascript
console.log(a); // undefined var a = 10;
(2)?let
?和?const
- 塊級作用域。
- 沒有變量提升。
- 作用域內只能聲明一次。
javascript
console.log(b); // 報錯:b未定義 let b = 20;
(3)?const
- 塊級作用域。
- 必須賦初始值。
- 不能重新賦值,但可以修改數組或對象的元素。
javascript
const arr = [1, 2, 3]; arr.push(4); // 允許 arr = []; // 報錯
5. 函數提升
函數聲明會被提升到當前作用域的最前面。
(1) 函數聲明
- 提升函數聲明,但不提升調用。
javascript
foo(); // "Hello" function foo() {console.log("Hello"); }
(2) 函數表達式
- 必須先聲明賦值才能調用。
javascript
bar(); // 報錯:bar未定義 var bar = function() {console.log("World"); };
6. 函數參數
(1) 動態參數
- 使用?
arguments
?對象(偽數組)。javascript
function sum() {let total = 0;for (let i = 0; i < arguments.length; i++) {total += arguments[i];}return total; } console.log(sum(1, 2, 3)); // 6
(2) 剩余參數
- 使用?
...
?獲取多余實參(真數組)。javascript
function sum(...nums) {return nums.reduce((a, b) => a + b); } console.log(sum(1, 2, 3)); // 6
(3) 展開運算符
- 展開數組,不會修改原數組。
javascript
const arr1 = [1, 2]; const arr2 = [3, 4]; const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]
7. 必須加分號的兩種情況
(1) 立即執行函數
javascript
(function() {console.log("IIFE");
})();
(2) 使用數組的時候
javascript
const arr = [1, 2, 3];
[].push.apply(arr, [4, 5]);
8. 箭頭函數
(1) 特點
this
?是靜態的,指向聲明時的作用域。- 不能作為構造函數實例化對象。
- 不能使用?
arguments
?對象。javascript
const add = (a, b) => a + b; console.log(add(1, 2)); // 3
9. Symbol
- 類似字符串的第七種基本數據類型。
- 值是唯一的。
- 不能與其他數據進行運算。
- 不能遍歷。
javascript
const id = Symbol("id"); const obj = {[id]: 123 }; console.log(obj[id]); // 123
10. 生成器函數
- 用于異步編程。
javascript
function* generator() {yield 1;yield 2; } const gen = generator(); console.log(gen.next().value); // 1
11. Promise
- 封裝異步操作并獲取成功或失敗的結果。
javascript
const promise = new Promise((resolve, reject) => {setTimeout(() => resolve("Success"), 1000); }); promise.then((result) => console.log(result)); // "Success"
12.?async
?和?await
(1)?async
- 返回一個 Promise 對象。
javascript
async function foo() {return "Hello"; } foo().then((result) => console.log(result)); // "Hello"
(2)?await
- 必須寫在?
async
?函數中。 - 等待 Promise 完成并返回結果。
javascript
async function bar() {const result = await Promise.resolve("World");console.log(result); // "World" } bar();