4182 字
21 分钟
JavaScript 核心知识点 - 面试必备Anki卡片集

一套完整的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; // 后缀n
console.log(bigNum + 1n); // 正确计算大数

类型检测

  • typeof null"object"(历史遗留问题)
  • 检测数组:Array.isArray()
  • 通用检测:Object.prototype.toString.call(value)

概念:JS中的数据类型检测方案?#

答案

1. typeof

  • 优点:快速识别基本类型
  • 缺陷
    • null"object"
    • 数组/对象无法区分 → 均返回 "object"

2. instanceof

  • 原理:在原型链上查找构造函数
  • 优点:检测引用类型(如 [] instanceof Arraytrue
  • 缺陷
    • 基本类型无效(1 instanceof Numberfalse
    • 跨框架失效

3. Object.prototype.toString.call()

  • 终极方案:返回 [object Type]
  • 示例
    • call(null)"[object Null]"
    • call([])"[object Array]"
  • 优势:精准识别所有类型(包括内置对象)

总结

  • 基本类型:优先 typeof(避开 null
  • 引用类型instanceof.toString.call()
  • 通用检测:封装 .toString.call() 为工具函数

概念:new运算符的实现?#

答案

实现步骤

  1. 创建空对象 const obj = {}
  2. 链接原型 obj.__proto__ = Constructor.prototype
  3. 绑定 this 执行构造函数 Constructor.call(obj, ...args)
  4. 返回对象
    • 构造函数返回对象 → 返回该对象
    • 未返回对象 → 返回 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.thenMutationObserver
    • 宏任务setTimeoutsetInterval、DOM事件

浏览器事件环

  1. 执行栈清空后,优先清空微任务队列
  2. 执行一个宏任务后,再次清空微任务队列
  3. 循环执行(宏任务 → 微任务 → 渲染)

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 // true
Person.prototype.__proto__ === Object.prototype // true
Object.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]

参数处理

// 需用剩余参数替代arguments
const 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声明提升 → 值为undefinedconsole.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个核心知识点:

  1. JavaScript 属性遍历方式及区别 - 掌握5种遍历方法的特点和适用场景
  2. JS中的8种数据类型及区别 - 理解基本类型与引用类型的本质差异
  3. JS中的数据类型检测方案 - 学会3种检测方法的优缺点和最佳实践
  4. new运算符的实现 - 深入理解new操作符的4个执行步骤
  5. bind、apply、call 区别 - 掌握this绑定的3种方法对比
  6. EventLoop 事件循环 - 理解浏览器和Node.js的事件循环机制
  7. JavaScript 的 this 绑定规则 - 掌握4种this绑定优先级
  8. 事件委托(Event Delegation) - 学会利用冒泡机制优化事件处理
  9. 什么是闭包(closure),为什么使用闭包 - 理解闭包的3大核心作用
  10. 作用域和作用域链 - 掌握词法作用域和变量查找机制
  11. 原型 && 原型链 - 深入理解JavaScript继承机制
  12. 箭头函数 vs 普通函数 - 掌握两种函数的核心差异
  13. 请描述事件冒泡 - 理解DOM事件传播机制
  14. 请解释变量提升(hoisting)和函数提升 - 掌握4种声明方式的提升规则
  15. 模块化发展历程 - 了解从IIFE到ES Module的演进过程
  16. 箭头函数示例 vs 常规函数对比 - 通过实例理解语法和this绑定差异
  17. 请解释同步和异步函数之间的区别 - 掌握阻塞与非阻塞执行机制

🚀 使用建议#

学习顺序#

建议按照以下顺序学习:

  1. 基础概念:数据类型、作用域、变量提升
  2. 函数机制:this绑定、闭包、箭头函数
  3. 对象系统:原型链、new运算符
  4. 事件机制:事件冒泡、事件委托
  5. 异步编程:EventLoop、同步异步
  6. 模块化:发展历程和现代实践

复习策略#

  • 每日复习:选择3-5张卡片进行复习
  • 分类练习:按概念、问题、实战分类练习
  • 实战应用:结合实际项目理解概念
  • 定期回顾:每周回顾所有卡片,巩固记忆

扩展学习#

  • 结合具体框架(React、Vue)理解概念应用
  • 通过LeetCode等平台练习JavaScript算法
  • 关注ES6+新特性和最佳实践
  • 学习TypeScript增强类型理解

这套卡片集将持续更新,添加更多实用的JavaScript知识点。建议收藏并定期复习,让JavaScript知识体系更加完善!

JavaScript 核心知识点 - 面试必备Anki卡片集
https://website-truelovings-projects.vercel.app/posts/frontend/javascript-interview/
作者
欢迎来到StarSky的网站!
发布于
2025-09-06
许可协议
CC BY-NC-SA 4.0