
2026-08-03 · 阅读 7
JavaScript复习总结
JS
JavaScript核心知识点总结
第一天基础夯实复习内容,涵盖原型链、闭包、作用域、异步编程、ES6+新特性
📚 目录
1. 原型链
核心概念
原型链是JavaScript实现继承的机制。每个对象都有一个__proto__属性,指向其构造函数的prototype。
关键理解
- 每个函数都有一个
prototype属性(原型对象) - 每个对象都有一个
__proto__属性(指向构造函数的prototype) - 当访问对象属性时,会沿着原型链向上查找
- 原型链的终点是
null
标准模板
// 创建父类
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(this.name + '在吃东西');
};
// 创建子类继承父类(5步固定写法)
function Dog(name, breed) {
// 步骤1:继承父类属性
Animal.call(this, name);
// 步骤2:子类自己的属性
this.breed = breed;
}
// 步骤3:继承父类方法
Dog.prototype = Object.create(Animal.prototype);
// 步骤4:修正constructor指向
Dog.prototype.constructor = Dog;
// 步骤5:添加子类自己的方法
Dog.prototype.bark = function() {
console.log(this.name + '汪汪叫');
};
// 创建实例
const dog = new Dog('旺财', '金毛');
dog.eat(); // 继承的方法
dog.bark(); // 子类自己的方法
原型链图解
dog实例
│
├── name: '旺财'
├── breed: '金毛'
│
└── __proto__ → Dog.prototype
│
├── bark()
├── constructor → Dog
│
└── __proto__ → Animal.prototype
│
├── eat()
│
└── __proto__ → Object.prototype
│
├── toString()
│
└── __proto__ → null
2. 闭包
核心概念
闭包是指有权访问另一个函数作用域中变量的函数,即使外部函数已经执行结束。
三大应用场景
场景1:数据私有化(最常用)
function createCounter() {
let count = 0; // 私有变量
return {
increment() {
count++;
return count;
},
decrement() {
count--;
return count;
},
getCount() {
return count;
}
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
场景2:函数工厂
function createMultiplier(倍数) {
return function(数值) {
return 数值 * 倍数;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
场景3:记忆化/缓存
function memoize(原函数) {
const cache = {};
return function(...args) {
const key = args.join(',');
if (cache[key] !== undefined) {
console.log('从缓存返回');
return cache[key];
}
const result = 原函数(...args);
cache[key] = result;
console.log('计算并缓存');
return result;
};
}
常见陷阱:循环中的闭包
// ❌ 错误示例
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i); // 输出:3, 3, 3
}, 100);
}
// ✅ 解决方案1:使用let
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i); // 输出:0, 1, 2
}, 100);
}
// ✅ 解决方案2:使用IIFE
for (var i = 0; i < 3; i++) {
(function(j) {
setTimeout(function() {
console.log(j); // 输出:0, 1, 2
}, 100);
})(i);
}
3. 作用域
三种作用域
- 全局作用域:整个程序可见
- 函数作用域:函数内部可见
- 块级作用域:
let/const在{}内可见
作用域链
const globalVar = '全局';
function outerFunction() {
const outerVar = '外部函数';
function innerFunction() {
const innerVar = '内部函数';
console.log(innerVar); // ✅ 当前作用域
console.log(outerVar); // ✅ 外部函数作用域
console.log(globalVar); // ✅ 全局作用域
}
innerFunction();
}
var vs let vs const
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | ✅ 是 | ❌ 否 | ❌ 否 |
| 重复声明 | ✅ 允许 | ❌ 不允许 | ❌ 不允许 |
| 重新赋值 | ✅ 允许 | ✅ 允许 | ❌ 不允许 |
| 初始化 | 可选 | 可选 | 必须初始化 |
最佳实践
- 优先使用
const,其次let,尽量避免var - 在需要的地方声明变量,避免变量提升带来的困惑
- 使用IIFE或块级作用域封装代码,避免污染全局
4. 异步编程
三种异步方式对比
方式1:回调函数(传统方式)
function fetchData(callback) {
setTimeout(() => {
callback(null, { id: 1, name: '张三' });
}, 1000);
}
fetchData((error, data) => {
if (error) {
console.error(error);
return;
}
console.log(data);
});
方式2:Promise(现代方式)
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id: 1, name: '张三' });
}, 1000);
});
}
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => console.log('清理工作'));
方式3:async/await(最优雅)
async function getData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
事件循环机制(重要!)
执行顺序:
同步代码 → 所有微任务 → 一个宏任务 → 所有微任务 → 循环...
示例:
console.log('1'); // 同步
setTimeout(() => console.log('2'), 0); // 宏任务
Promise.resolve().then(() => console.log('3')); // 微任务
console.log('4'); // 同步
// 输出顺序:1, 4, 3, 2
原因:
- 同步代码先执行(1, 4)
- 微任务队列优先于宏任务队列(3)
- 宏任务最后执行(2)
Promise.all vs Promise.race
// Promise.all:等所有完成
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json())
]);
// Promise.race:返回最先完成的
const result = await Promise.race([
fetch('/api/fast'),
fetch('/api/slow')
]);
实战案例:倒计时
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function countdown(seconds) {
for (let i = seconds; i > 0; i--) {
console.log(i);
await delay(1000);
}
console.log('发射!');
}
countdown(10);
5. ES6+新特性
解构赋值
// 对象解构
const { name, age, city: cityName } = person;
// 数组解构
const [first, second, ...rest] = numbers;
// 函数参数解构
function greet({ name, age = 20 }) {
console.log(`你好,我是${name},今年${age}岁`);
}
展开运算符
// 数组展开
const merged = [...arr1, ...arr2];
// 对象展开
const newObj = { ...obj1, ...obj2 };
// Rest参数
function sum(...args) {
return args.reduce((total, num) => total + num, 0);
}
箭头函数
const add = (a, b) => a + b;
const square = x => x * x;
// 注意:箭头函数没有自己的this
const obj = {
name: '对象',
normalFunc() {
console.log(this.name); // ✅ '对象'
},
arrowFunc: () => {
console.log(this.name); // ❌ undefined
}
};
模板字符串
const greeting = `你好,我是${name},今年${age}岁。`;
// 多行字符串
const html = `
<div>
<h1>${title}</h1>
</div>
`;
类和继承
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name}发出声音`);
}
static info() {
console.log('这是Animal类');
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() {
console.log(`${this.name}汪汪叫`);
}
}
可选链操作符(?.)
const age = user?.profile?.age; // 安全访问,不会报错
const result = obj.method?.(); // 安全调用方法
空值合并运算符(??)
// || 运算符:falsy值都会使用右侧
console.log(0 || '默认值'); // '默认值'
console.log('' || '默认值'); // '默认值'
// ?? 运算符:只有null和undefined才使用右侧
console.log(0 ?? '默认值'); // 0(保留)
console.log('' ?? '默认值'); // ''(保留)
console.log(null ?? '默认值'); // '默认值'
📝 学习建议
理解优先级
- 原型链:理解继承机制,掌握5步继承模板
- 闭包:理解三大应用场景,避免常见陷阱
- 作用域:理解作用域链,区分var/let/const
- 异步编程:掌握async/await,理解事件循环
- ES6+新特性:掌握常用语法,提升开发效率
练习建议
- 先理解概念,再看代码示例
- 动手敲代码,不要只看不练
- 尝试修改示例代码,观察变化
- 完成每个知识点的练习题
常见陷阱
- 原型链忘记修正constructor
- 循环中使用var导致闭包问题
- 箭头函数误用导致this指向错误
- 异步操作不理解事件循环机制
🎯 总结
JavaScript核心知识点可以归纳为:
- 原型链:实现继承的机制,掌握标准模板
- 闭包:数据私有化、函数工厂、缓存的利器
- 作用域:理解作用域链,合理使用var/let/const
- 异步编程:async/await最优雅,理解事件循环
- ES6+新特性:掌握解构、箭头函数、类等常用特性
掌握这些核心概念,就能在面试和实际开发中游刃有余!