菜单

涵盖的 JavaScript 概念

相关源文件

本文概述了本仓库中问题所测试的 JavaScript 概念。这些问题涵盖了从基础到高级的 JavaScript 主题,这些主题在编码面试和专业开发中很常见。

本仓库侧重于测试对 JavaScript 核心行为、边缘情况和常见误解特性的理解,而非特定框架或库。

核心 JavaScript 概念图

本仓库中的问题测试了以下几个关键 JavaScript 概念领域的知识

来源: README.md53-1121/README.md2127-2161

变量与作用域

JavaScript 提供了三种声明变量的方式(varletconst),每种方式在作用域、变量提升和重新赋值方面都有不同的行为。

提升 (Hoisting)

变量提升(Hoisting)是 JavaScript 在编译阶段将声明提升到其包含作用域顶部的行为。

  • var 声明会被提升并初始化为 undefined
  • letconst 声明会被提升,但不会被初始化(它们在执行到达声明行之前,会处于“暂时性死区”)。
  • 函数声明会被完全提升(声明和定义都会被提升)。

示例问题

在此示例中,name 被提升并初始化为 undefined 值,但 age 在其声明行之前处于暂时性死区。

块级作用域 vs. 函数作用域

问题中测试的一个关键概念是变量作用域之间的区别

  • var 具有函数作用域 — 它只受函数边界的限制。
  • letconst 具有块级作用域 — 它们受任何代码块(函数、循环、if 语句)的限制。

示例

来源: README.md53-112/README.md725-748

函数与 this 上下文

JavaScript 有几种类型的函数,每种函数在 this 关键字方面都有不同的行为。

函数类型及其行为

  1. 常规函数: 通过函数声明或表达式创建。

    • 拥有自己的 this 上下文,取决于它们的调用方式。
    • 可以使用 new 作为构造函数使用。
  2. 箭头函数: 使用 => 语法。

    • 从周围的代码继承 this
    • 不能用作构造函数。
    • 没有 arguments 对象。
  3. 方法函数: 附属于对象的函数。

    • this 指向拥有该方法的对象。
    • 如果将方法赋值给变量,其行为会改变。
  4. 构造函数: 与 new 关键字一起使用来创建对象。

    • this 指向新创建的实例。
    • 根据约定,通常以大写字母开头。

示例问题

在这里,方法 diameter 使用常规函数,其中 this 指向 shape,而箭头函数 perimeter 从外部作用域继承 this(它不是 shape)。

闭包

闭包发生在函数即使在其词法作用域之外执行时,仍然能够访问其词法作用域的情况下。

此示例演示了一个标签模板字面量,其中函数接收模板字符串的各个部分和表达式。

来源: README.md116-145/README.md376-413/README.md1024-1053

对象与原型

JavaScript 是基于原型的:对象从原型对象继承属性和方法。

对象创建

JavaScript 提供了多种创建对象的方式

  • 对象字面量: {}
  • 构造函数: new Constructor()
  • Object.create()
  • ES6 类: class 语法(原型继承的语法糖)

示例

在此示例中,lydia 作为新的对象实例被创建,而没有 new 关键字调用 Person 会导致 this 指向全局对象。

原型链

每个 JavaScript 对象都有一个原型,并从该原型继承属性。

  • 原型链用于属性查找。
  • 基对象的原型是 null
  • 并非所有对象都有原型(例如基对象 Object 的原型)。

示例问题

这演示了如何扩展类的原型以添加所有实例都可以访问的方法。

来源: README.md472-485/README.md700-769/README.md1697-1733

异步 JavaScript

JavaScript 使用事件驱动的单线程模型处理异步操作。

事件循环

事件循环(Event Loop)是 JavaScript 执行非阻塞操作的机制。

  1. JavaScript 在调用栈(Call Stack)上执行代码。
  2. 异步操作被委托给 Web API。
  3. 当这些操作完成时,它们的回调函数会进入回调队列(Callback Queue)。
  4. 事件循环检查调用栈是否为空,然后将回调函数从队列移动到栈中。

示例

这演示了事件循环如何优先处理同步代码,然后再处理队列中的回调函数。

Promise

Promise 是代表异步操作最终完成(或失败)的对象。

  • Promise 对象有三种状态:pending(待定)、fulfilled(已完成)或 rejected(已拒绝)。
  • .then() 处理完成情况,.catch() 处理拒绝情况。
  • Promise 方法如 race()all() 用于组合多个 Promise。

示例

来源: README.md914-963/README.md1373-1402

类型强制转换与运算符

当操作涉及不同类型时,JavaScript 会执行自动类型转换。

JavaScript 类型

JavaScript 有两大类数据类型

  • 原始类型: 不可变值,按值传递。
    • string, number, boolean, null, undefined, symbol, bigint
  • 引用类型: 对象,按引用传递。
    • Object, Array, Function, Date, RegExp 等。

示例

此问题测试对 typeof 操作符及其返回值的理解。

类型强制转换

类型强制转换是值的自动或手动转换。

  • 隐式强制转换: 操作过程中自动进行的转换。
  • 显式强制转换: 使用 Number()String() 等方法进行手动转换。

示例

这演示了 JavaScript 在使用 + 操作符进行字符串连接时,如何将数字转换为字符串。

真值与假值

在 JavaScript 中,值在布尔上下文中具有固有的布尔值。

  • Falsy 值: false, 0, '' (空字符串), null, undefined, NaN
  • Truthy 值: 其他所有值(包括 {}, [] 等)。

示例

这展示了逻辑非操作符(!)如何将值转换为其布尔等价物。

来源: README.md1085-1117/README.md1474-1497/README.md1263-1290

DOM 与事件

JavaScript 可以操作文档对象模型(DOM)并处理浏览器事件。

事件传播

DOM 事件在 DOM 树中通过三个阶段传播。

  1. 捕获阶段: 事件从窗口向下传播到目标元素。
  2. 目标阶段:事件到达目标元素
  3. 冒泡阶段: 事件从目标元素向上冒泡回窗口。

示例

当点击段落时,事件按 pdiv 的顺序触发,演示了事件冒泡。

Event Target vs currentTarget

  • event.target: 触发事件的元素。
  • event.currentTarget: 附加事件处理程序的元素。

这些属性有助于管理事件委托模式,其中父元素上的单个处理程序管理来自多个子元素的事件。

来源: README.md452-468/README.md996-1020

ES6+ 特性

ECMAScript 2015 (ES6) 及更高版本为 JavaScript 引入了许多重要特性。

ES6+ 关键特性

  1. 变量声明: letconst 提供块级作用域。
  2. 箭头函数: 简洁的语法和词法 this 绑定。
  3. 解构: 从对象和数组中提取值。
  4. 展开/剩余操作符: 展开或收集元素。
  5. 模板字面量: 使用反引号进行字符串插值。
  6. 模块: 使用 importexport 组织代码。
  7. 生成器: 可以暂停和恢复执行的函数。
  8. 集合: Map, Set, WeakMap, WeakSet

来源: README.md1339-1371/README.md1740-1764/README.md1849-1894

Web API

JavaScript 通过各种 Web API 与浏览器交互。

存储 API

仓库涵盖了浏览器存储机制。

  • localStorage: 持久存储,无过期时间。
  • sessionStorage: 存储仅限于当前会话。
  • Cookies: 常用于身份验证的小数据片段。

示例

此问题测试对 sessionStorage 数据持久性(直到浏览器标签关闭)的理解。

计时函数

浏览器计时函数控制代码的执行时间。

  • setTimeout(): 在延迟后执行代码并返回一个 ID。
  • setInterval(): 以固定间隔重复执行代码。
  • clearTimeout()clearInterval(): 取消计划的执行。

示例

这会创建一个重复的间隔,每秒记录“Hi”并返回一个唯一的 ID。

来源: README.md699-721/README.md1296-1315

概念关系与高级模式

许多 JavaScript 概念以复杂的方式相互作用。本仓库的问题测试了对这些交互的理解。

高级 JavaScript 模式

本仓库测试了对包括以下高级模式的知识:

  1. 模块模式: 使用闭包创建私有数据。
  2. 构造函数模式: 创建具有共享方法的对象。
  3. 工厂模式: 返回新对象的函数。
  4. IIFE(立即调用函数表达式): 创建隔离作用域。

示例

这演示了在 catch 块中的变量遮蔽和 IIFE 作用域隔离。

语言边缘情况

本仓库探讨了语言的边缘情况和怪异行为。

  • 操作期间的类型强制转换: "1" == 1 对比 "1" === 1
  • 非对象上的属性访问: 'foo'.toUpperCase()
  • 对象到原始类型的转换: String({})
  • this 上下文绑定规则和边界情况。

示例

这演示了字符串原始类型如何临时转换为 String 对象,从而允许方法调用。

来源: README.md868-877/README.md1177-1208

总结

本仓库中的 JavaScript 问题旨在测试对核心语言机制的理解,而非特定框架知识。这些问题旨在揭示在实际代码中经常导致错误的细微行为和边缘情况。

涵盖的概念代表了 JavaScript 编程的基本组成部分,从基本语言特性到更高级的模式和异步编程技术。透彻理解这些概念有助于开发人员编写更可预测和可维护的 JavaScript 代码。

重点关注的关键领域包括

  • 变量和作用域规则
  • 函数行为和 this 绑定
  • 对象操作和原型继承
  • 异步代码执行
  • 类型强制转换规则
  • ES6+ 特性采用

来源: README.md6-18