目录
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();