
一套完整的JavaScript核心知识点Anki记忆卡片集,包含17个重要概念,涵盖从基础语法到高级特性的全面内容。
📚 卡片概览
本卡片集包含以下类型的学习内容:
- 概念类:深入理解JavaScript核心原理和机制
- 问题类:解决实际开发中的常见问题
- 实战类:掌握具体的代码实现技巧
📥 Anki 卡包下载
Anki 卡包下载地址:https://ankiweb.net/shared/info/1277333752
点击上方链接即可在 Anki 中导入这套完整的 JavaScript 核心知识点卡片集,支持 Anki 2.1+ 版本。
🎯 学习目标
通过这套卡片,您将掌握:
- JavaScript数据类型和类型检测
- 作用域和作用域链机制
- 原型和原型链继承
- 事件机制和异步编程
- 函数和闭包的高级应用
- 模块化开发实践
📋 知识点清单
概念:JavaScript 属性遍历方式及区别?
答案:
方法 | 范围 | 原型链 | 不可枚举 | Symbol | 记忆口诀 |
---|---|---|---|---|---|
for...in | 自身+原型链 | ✅ | ❌ | ❌ | 原型链专用 |
Object.keys() | 仅自身 | ❌ | ❌ | ❌ | 最常用 |
Object.getOwnPropertyNames() | 仅自身 | ❌ | ✅ | ❌ | 包含不可枚举 |
Object.getOwnPropertySymbols() | 仅自身 | ❌ | ✅ | ✅ | Symbol专用 |
Reflect.ownKeys() | 仅自身 | ❌ | ✅ | ✅ | 最全面 |
核心区别:
- 原型链:仅
for...in
- 不可枚举:后三种包含
- Symbol:仅后两种支持
- 最全面:
Reflect.ownKeys()
使用场景:
- 过滤原型链 →
Object.keys()
- 完整遍历 →
Reflect.ownKeys()
概念:JS中的8种数据类型及区别?
答案:
基本类型(值类型):
Number
:数值类型(整数/浮点数/NaN)String
:字符串类型Boolean
:布尔值(true/false)Undefined
:未定义值(声明未赋值)Null
:空值(需显式赋值)Symbol
(ES6):唯一不可变值(用于对象属性键)BigInt
(ES2020):大整数(表示超过2^53的整数)
引用类型:
Object
:对象类型(包含Array、Function、Date等)
核心区别:
特性 | 基本类型 | 引用类型 |
---|---|---|
存储位置 | 栈内存(直接存储值) | 堆内存(存储内存地址) |
复制行为 | 值复制(创建独立副本) | 引用复制(共享内存) |
比较方式 | 值相等比较 | 内存地址比较 |
内存管理 | 固定大小,自动回收 | 动态大小,GC回收 |
特殊类型说明:
Symbol:
const key = Symbol('description');obj[key] = '私有属性'; // 避免属性名冲突
BigInt:
const bigNum = 9007199254740991n; // 后缀nconsole.log(bigNum + 1n); // 正确计算大数
类型检测:
typeof null
→"object"
(历史遗留问题)- 检测数组:
Array.isArray()
- 通用检测:
Object.prototype.toString.call(value)
概念:JS中的数据类型检测方案?
答案:
1. typeof
- 优点:快速识别基本类型
- 缺陷:
null
→"object"
- 数组/对象无法区分 → 均返回
"object"
2. instanceof
- 原理:在原型链上查找构造函数
- 优点:检测引用类型(如
[] instanceof Array
→true
) - 缺陷:
- 基本类型无效(
1 instanceof Number
→false
) - 跨框架失效
- 基本类型无效(
3. Object.prototype.toString.call()
- 终极方案:返回
[object Type]
- 示例:
call(null)
→"[object Null]"
call([])
→"[object Array]"
- 优势:精准识别所有类型(包括内置对象)
总结:
- 基本类型:优先
typeof
(避开null
) - 引用类型:
instanceof
或.toString.call()
- 通用检测:封装
.toString.call()
为工具函数
概念:new运算符的实现?
答案:
实现步骤:
- 创建空对象
const obj = {}
- 链接原型
obj.__proto__ = Constructor.prototype
- 绑定 this 执行构造函数
Constructor.call(obj, ...args)
- 返回对象
- 构造函数返回对象 → 返回该对象
- 未返回对象 → 返回 obj
手写实现:
function myNew(Con, ...args) { const obj = Object.create(Con.prototype); // 步骤1+2 const result = Con.apply(obj, args); // 步骤3 return result instanceof Object ? result : obj; // 步骤4}
本质:建立对象与构造函数原型链关系 + this 绑定
概念:bind、apply、call 区别?
答案:
方法 | 执行时机 | 参数形式 | 返回值 |
---|---|---|---|
call | 立即执行 | 参数列表 | 函数执行结果 |
apply | 立即执行 | 数组 | 函数执行结果 |
bind | 不执行 | 参数列表/分次 | 绑定后的函数 |
关键特性:
1. call/apply:
- 一次性修改 this 并立即执行
showInfo.apply(user, ['arg1', 'arg2']);showInfo.call(user, 'arg1', 'arg2');
2. bind:
- 永久绑定 this(可多次传参)
const boundFunc = showInfo.bind(user);boundFunc('arg1'); // 后续执行
共用规则:
- 首参数为 this 指向(null/undefined → 全局对象)
- 支持函数柯里化(分次传参)
概念:EventLoop 事件循环?
答案:
核心流程:
- 同步任务:直接推入调用栈执行
- 异步任务:
- 微任务:
Promise.then
、MutationObserver
- 宏任务:
setTimeout
、setInterval
、DOM事件
- 微任务:
浏览器事件环:
- 执行栈清空后,优先清空微任务队列
- 执行一个宏任务后,再次清空微任务队列
- 循环执行(宏任务 → 微任务 → 渲染)
Node.js 事件环: 包含6个阶段:
- Timers:执行setTimeout/setInterval回调
- Poll:处理I/O回调(核心阶段)
- Check:执行setImmediate回调
关键区别:
- Node 11+ 后微任务执行时机与浏览器一致
- 旧版Node在阶段切换时清空微任务
经典面试题输出:
setTimeout(() => console.log(1), 0);Promise.resolve().then(() => console.log(2));console.log(3);// 输出:3 → 2 → 1
概念:JavaScript 的 this 绑定规则?
答案:
核心规则(按优先级排序):
1. new 绑定(最高)
function Car() { this.color = 'red';}const bmw = new Car(); // this = 新对象(bmw)
2. 显式绑定(call/apply/bind)
function run() { console.log(this); }run.call({ speed: 100 }); // this = { speed: 100 }
3. 隐式绑定(上下文对象调用)
const obj = { name: "Alice", greet() { console.log(this.name); }};obj.greet(); // this = obj → "Alice"
4. 默认绑定(最低)
function log() { console.log(this); }log(); // 非严格模式:this = window// 严格模式('use strict'):this = undefined
5. 特殊规则
- 箭头函数:继承外层词法作用域的 this(定义时确定)
const outer = { name: "Outer", inner: () => console.log(this.name) // this = window(非对象自身)};outer.inner(); // ""
6. 绑定优先级验证
const obj1 = { name: "obj1" };const obj2 = { name: "obj2" };
function showName() { console.log(this.name); }
// 显式绑定 > 隐式绑定showName.call(obj1); // "obj1"(显式)obj2.show = showName;obj2.show(); // "obj2"(隐式)
// new 绑定 > 显式绑定const boundFunc = showName.bind(obj1);const instance = new boundFunc(); // this = 新对象(忽略obj1)
总结:new > 显式 > 隐式 > 默认
箭头函数无视上述规则,由词法作用域决定
概念:事件委托(Event Delegation)?
答案:
核心原理:
- 冒泡机制:子元素事件触发 → 向父元素逐层冒泡
- 委托监听:在父元素统一监听子元素事件
实现方式:
// 父元素统一监听document.getElementById("parent").addEventListener("click", (e) => { if (e.target.matches("li")) { // 过滤目标元素 console.log("子元素被点击:", e.target.textContent); }});
核心优势:
- 内存优化:单监听器替代多个子元素监听器(减少80%+内存占用)
- 动态适配:自动处理新增/删除子元素(无需重新绑定)
- 性能提升:避免频繁绑定/解绑事件(如长列表)
适用场景:
- 列表/表格交互
- 动态内容容器
- 嵌套组件事件管理
概念:什么是闭包(closure),为什么使用闭包?
答案:
定义: 函数与其定义时的词法作用域的组合,使函数能访问外部作用域变量(即使外部函数已执行完毕)。
核心作用:
1. 数据私有化
- 封装变量,避免全局污染
const createCounter = () => { let count = 0; return () => count++; // 外部无法直接修改 count};
2. 柯里化与部分应用
- 预置参数生成新函数
const multiply = a => b => a * b;const double = multiply(2);double(3); // 6
3. 模块化开发
- 实现模块模式(IIFE 封装私有变量)
const module = (() => { const privateVar = 10; return { get: () => privateVar };})();
使用场景:
- 事件回调(保留上下文)
- 防抖/节流函数
- 缓存计算结果
注意:过度使用可能导致内存泄漏(无用变量无法回收)
概念:作用域和作用域链?
答案:
定义: 简单来说作用域就是变量与函数的可访问范围,由当前环境与上层环境的一系列变量对象组成
作用域类型:
1. 全局作用域:
- 代码在程序的任何地方都能被访问
- window 对象的内置属性都拥有全局作用域
2. 函数作用域:
- 在固定的代码片段才能被访问
作用: 作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
作用域链: 一般情况下,变量到创建该变量的函数的作用域中取值。但是如果在当前作用域中没有查到,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
概念:原型 && 原型链?
答案:
核心关系:
构造函数:
- 拥有
prototype
属性(显式原型)
实例对象:
- 拥有
__proto__
属性(隐式原型)
原型链:
实例.__proto__
→构造函数.prototype
构造函数.prototype.__proto__
→ 父级原型(直至Object.prototype
)
原型链终点:
Object.prototype.__proto__ === null
特性验证:
function Person() {}const p = new Person();
// 原型关系p.__proto__ === Person.prototype // truePerson.prototype.__proto__ === Object.prototype // trueObject.prototype.__proto__ === null // true
// 构造函数指向Person.prototype.constructor === Person // true
动态继承特性:
- 修改原型立即影响所有实例
Person.prototype.say = () => console.log("Hello");p.say(); // "Hello"(已继承新方法)
ES6 Class 本质:
class Student {}typeof Student // "function"(构造函数)Student.prototype.__proto__ === Object.prototype // true
设计意义:
- 实现方法与属性共享(节省内存)
- 构建对象继承体系
- 扩展内置对象功能(如给 Array 添加自定义方法)
注意事项:
- 避免过长原型链(性能问题)
- 谨慎修改内置对象原型(可能引发冲突)
概念:箭头函数 vs 普通函数?
答案:
核心区别(vs 普通函数):
特性 | 箭头函数 | 普通函数 |
---|---|---|
this绑定 | 继承外层词法作用域 | 动态绑定(调用方决定) |
构造函数 | ❌ 不可用new调用 | ✅ 可用作构造函数 |
arguments | ❌ 不存在 | ✅ 存在 |
原型链 | ❌ 无prototype属性 | ✅ 有prototype |
生成器 | ❌ 不可用yield | ✅ 支持生成器语法 |
关键特性详解:
固定this绑定:
const obj = { name: "Alice", print: () => console.log(this.name) // 继承全局this(window)};obj.print(); // 输出空(非"Alice")
简化语法(适合回调场景):
// 单行隐式返回const nums = [1, 2, 3];const squares = nums.map(n => n * n); // [1, 4, 9]
参数处理:
// 需用剩余参数替代argumentsconst sum = (...args) => args.reduce((a, b) => a + b);sum(1, 2, 3); // 6
使用限制:
- ❌ 不能用作构造函数(
new ArrowFunc()
报错) - ❌ 无法通过call/apply/bind修改this
- ❌ 不适合对象方法定义(this指向错误)
设计初衷:解决传统函数中this绑定的混淆问题,简化回调写法
最佳实践:事件处理器、map/filter等函数式操作、需要固定this的场景
概念:请描述事件冒泡?
答案:
核心机制:
- 自底向上传播:事件从触发的最深层元素开始
- 逐级穿透:事件依次经过所有父级元素直至文档根节点
示例结构:
<div class="祖父"> <div class="父亲"> <button class="子">点击</button> </div></div><!-- 点击按钮触发顺序:子 → 父亲 → 祖父 → body → html → document -->
关键特性:
- 默认阶段:DOM事件流包括捕获→目标→冒泡三阶段(冒泡为默认响应阶段)
- 可中断:通过
e.stopPropagation()
终止冒泡 - 事件委托基础:利用冒泡实现父元素统一监听
实际应用:
document.querySelector('.祖父').addEventListener('click', () => { console.log('祖父元素响应事件!'); // 通过冒泡触发});
注:与事件捕获方向相反(捕获:根元素→目标元素)
概念:请解释变量提升(hoisting)和函数提升?
答案:
核心机制:
- 声明提升:var与函数声明在代码执行前被提升至作用域顶部
- 赋值不提升:初始化赋值保留原位
不同声明对比:
声明方式 | 提升表现 | 示例 |
---|---|---|
var | 声明提升 → 值为undefined | console.log(a); // undefined var a=1; |
let/const | 不提升 → 触发暂时性死区(TDZ) | console.log(b); // ReferenceError let b=2; |
函数声明 | 整体提升(含函数体) | foo(); // 正常运行 function foo(){} |
函数表达式 | 变量提升(同var) | bar(); // TypeError var bar=function(){} |
关键规则:
- 函数声明 > 变量声明提升
- let/const 需先声明后使用
- 避免在块内使用函数声明(优先函数表达式)
概念:模块化发展历程?
答案:
IIFE 阶段:
- 自执行函数隔离作用域(如早期 jQuery)
- 通过 window 对象通信
CommonJS:
- Node.js 同步加载标准(require/module.exports)
AMD/CMD:
- 浏览器异步加载方案(Require.js/Sea.js)
- AMD 预加载 vs CMD 按需加载
UMD:
- 兼容 AMD/CMD/CommonJS 的通用格式
ES Module:
- 现代标准(import/export)
- 浏览器原生支持,编译时加载
演进方向:作用域隔离 → 同步加载 → 异步加载 → 统一标准 → 原生支持
概念:箭头函数示例 vs 常规函数对比?
答案:
语法简洁:
- 箭头函数:省略 function 关键字,单行可隐式返回
const sum = (a, b) => a + b
- 常规函数:需完整声明
this 绑定:
- 箭头函数:自动绑定定义时的上下文(静态)
- 常规函数:运行时确定(动态)
最佳场景:
- 箭头函数:回调函数、React 事件处理(避免 this 绑定问题)
- 常规函数:对象方法、构造函数
核心差异:箭头函数无独立 this,适合需要继承外围作用域的场景
概念:请解释同步和异步函数之间的区别?
答案:
同步函数:
- 阻塞执行:代码严格按顺序运行,必须等待当前操作完成后才执行下一行
- 问题:耗时操作(如网络请求)会导致界面冻结或线程阻塞
异步函数:
- 非阻塞执行:调用后立即执行后续代码,耗时操作完成后通过回调/Promise/事件通知结果
- 优势:主线程持续响应,避免界面卡顿
核心对比:
特性 | 同步 | 异步 |
---|---|---|
执行顺序 | 严格顺序(语句1→语句2→语句3) | 调用后立即继续后续任务 |
结果获取 | 直接返回值 | 通过回调/Promise异步获取结果 |
性能影响 | 易导致界面阻塞 | 主线程保持高响应性 |
使用场景:
- 必须异步:网络请求、文件读写、定时任务(防止阻塞)
- 可同步:简单计算、本地数据转换(快速无阻塞)
📝 知识点清单
本卡片集包含以下17个核心知识点:
- JavaScript 属性遍历方式及区别 - 掌握5种遍历方法的特点和适用场景
- JS中的8种数据类型及区别 - 理解基本类型与引用类型的本质差异
- JS中的数据类型检测方案 - 学会3种检测方法的优缺点和最佳实践
- new运算符的实现 - 深入理解new操作符的4个执行步骤
- bind、apply、call 区别 - 掌握this绑定的3种方法对比
- EventLoop 事件循环 - 理解浏览器和Node.js的事件循环机制
- JavaScript 的 this 绑定规则 - 掌握4种this绑定优先级
- 事件委托(Event Delegation) - 学会利用冒泡机制优化事件处理
- 什么是闭包(closure),为什么使用闭包 - 理解闭包的3大核心作用
- 作用域和作用域链 - 掌握词法作用域和变量查找机制
- 原型 && 原型链 - 深入理解JavaScript继承机制
- 箭头函数 vs 普通函数 - 掌握两种函数的核心差异
- 请描述事件冒泡 - 理解DOM事件传播机制
- 请解释变量提升(hoisting)和函数提升 - 掌握4种声明方式的提升规则
- 模块化发展历程 - 了解从IIFE到ES Module的演进过程
- 箭头函数示例 vs 常规函数对比 - 通过实例理解语法和this绑定差异
- 请解释同步和异步函数之间的区别 - 掌握阻塞与非阻塞执行机制
🚀 使用建议
学习顺序
建议按照以下顺序学习:
- 基础概念:数据类型、作用域、变量提升
- 函数机制:this绑定、闭包、箭头函数
- 对象系统:原型链、new运算符
- 事件机制:事件冒泡、事件委托
- 异步编程:EventLoop、同步异步
- 模块化:发展历程和现代实践
复习策略
- 每日复习:选择3-5张卡片进行复习
- 分类练习:按概念、问题、实战分类练习
- 实战应用:结合实际项目理解概念
- 定期回顾:每周回顾所有卡片,巩固记忆
扩展学习
- 结合具体框架(React、Vue)理解概念应用
- 通过LeetCode等平台练习JavaScript算法
- 关注ES6+新特性和最佳实践
- 学习TypeScript增强类型理解
这套卡片集将持续更新,添加更多实用的JavaScript知识点。建议收藏并定期复习,让JavaScript知识体系更加完善!