JavaScript & Web 前端关键知识总结

143 阅读6分钟

JavaScript & Web 前端关键知识总结

一、DOM(文档对象模型)

1. DOM 结构

  • 定义:DOM 是文档对象模型,将 HTML 或 XML 文档表示为可编程对象的树结构。
  • 树形结构:HTML 文档被解析为节点树,每个节点代表文档的一部分(元素、属性、文本等)。
  • 节点类型
    • Element:表示 HTML 元素
    • Text:表示文本内容
    • Document:表示整个文档
    • Comment:表示注释

示例:

<html>
  <body>
    <div id="main">
      <p>Hello World</p>
    </div>
  </body>
</html>

树结构表示:

Document
└── html
    └── body
        └── div#main
            └── p
                └── Text: "Hello World"

2. 常用 DOM 操作

  • 访问节点
    • document.getElementById("main"):通过 ID 访问元素
    • document.querySelector(".class"):通过 CSS 选择器访问第一个匹配的元素
    • document.querySelectorAll("p"):通过 CSS 选择器访问所有匹配的元素
  • 创建节点
    • document.createElement("div"):创建新的元素节点
    • document.createTextNode("Hello"):创建新的文本节点
  • 修改节点
    • element.appendChild(newElement):将新的子节点添加到现有节点
    • element.removeChild(childElement):从现有节点中移除子节点
    • element.replaceChild(newElement, oldElement):用新节点替换子节点
    • element.innerHTML = "<p>New Content</p>":设置 HTML 内容

示例:

const div = document.createElement("div");
div.textContent = "Hello World";
document.body.appendChild(div); // 添加到 body

二、闭包(Closure)

1. 概念

  • 定义:闭包是指有权访问另一个函数作用域中的变量的函数,即使外部函数已经返回,闭包依然可以访问和修改外部函数的变量。
  • 作用:闭包用于数据的私有化和延迟执行。

2. 特性

  • 数据封装:通过闭包,可以创建带有私有数据的函数。
  • 持久化状态:闭包可以记住其创建时的作用域中的变量值。

3. 使用场景

  • 函数工厂:生成不同的函数,每个函数有其独立的作用域。
  • 模块化:模拟私有方法和属性。

4. 示例

function outer() {
    let count = 0; // 外部变量
    return function inner() { // 内部函数
        count++; // 访问外部变量
        return count;
    };
}
const increment = outer(); // 创建闭包
console.log(increment()); // 1
console.log(increment()); // 2

三、TypeScript 静态类型系统

1. 优势

  • 类型检查:在编译时检查类型错误,减少运行时错误。
  • 代码提示:提供智能补全和文档提示,提高开发效率。
  • 代码可读性:明确变量、函数的预期类型,提高代码可读性。

2. 基本类型

  • 原始类型number,string,boolean,symbol,null,undefined
  • 对象类型object,array,function
  • 特殊类型any,void,unknown,never

3. 自定义类型

  • 接口( interface :定义对象的结构
  • 类型别名( type :定义类型别名或联合类型
let num: number = 42;
let str: string = "hello";

interface Person {
    name: string;
    age: number;
}

const person: Person = { name: "John", age: 30 };

type ID = number | string;
let userId: ID = 123; // or "abc"

4. 泛型(Generics)

  • 定义:泛型提供了一种在定义函数、接口或类时不指定具体类型,而在使用时指定类型的方法。
function identity<T>(arg: T): T {
    return arg;
}
let output = identity<string>("Hello"); // 使用时指定类型

更多。。。


四、Git 及其工作流

1. 基本概念

  • 版本控制:管理文件的更改历史,允许多用户协作开发。
  • 分支(Branch) :并行开发不同功能,保持代码稳定性,通过分支进行新功能开发和测试。

2. 常用命令

  • 初始化和克隆
    • git init:初始化新的 Git 仓库
    • git clone <url>:克隆远程仓库
  • 更改管理
    • git add <file>:将更改添加到暂存区
    • git commit -m "message":提交更改
  • 分支操作
    • git branch <branch>:创建新分支
    • git checkout <branch>:切换分支
    • git merge <branch>:合并分支
  • 同步操作
    • git pull:拉取远程更新并合并
    • git push:推送本地更改到远程
git init
git add .
git commit -m "Initial commit"

3. Rebase

  • 定义git rebase将一个分支上的更改应用到另一个分支上,以创建一个清晰的历史记录。
  • 用途:保持历史记录线性和整洁,避免合并冲突。
git checkout feature
git rebase main

更多。。。


五、Promise 及其异常捕获机制

1. 概念

  • 定义:Promise 是表示异步操作最终完成或失败的对象。
  • 状态
    • pending:进行中
    • fulfilled:已成功
    • rejected:已失败

2. 使用方法

  • then:处理成功结果
  • catch:处理错误
  • finally:无论成功与否都会执行

3. 异常捕获

  • 在 Promise 链中catch可以捕获链中发生的任何错误。
  • async/await:使用try...catch捕获异常。
new Promise((resolve, reject) => {
    resolve("Success");
})
.then(value => console.log(value))
.catch(error => console.error(error))
.finally(() => console.log("Done"));

async function fetchData() {
    try {
        let response = await fetch("url");
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error(error);
    } finally {
        console.log("Fetch complete");
    }
}
fetchData();

六、重排(Reflow)与重绘(Repaint)

1. 重排(Reflow)

  • 定义:重新计算元素的几何结构(尺寸、位置等)。
  • 触发条件:元素尺寸、位置变化、DOM 变动、窗口大小改变等。
element.style.width = "100px"; // 触发重排
  • 代价:重排代价高,需要重新计算布局和渲染树。

2. 重绘(Repaint)

  • 定义:重新绘制元素的外观(颜色、背景、边框等)。
  • 触发条件:元素的颜色、背景图、文字颜色等变化。
element.style.backgroundColor = "red"; // 触发重绘
  • 代价:重绘比重排代价低,但频繁重绘也会影响性能。

3. 优化策略

  • 减少 DOM 操作:合并多次修改,减少频繁操作 DOM。
  • 使用 documentFragment:在内存中操作,最后一次性添加到 DOM。
  • 批量操作 CSS 类:替代逐一设置内联样式。

七、JavaScript 事件机制

1. 事件传播

  • 捕获阶段:从祖先到目标,检查事件是否应该触发。
  • 目标阶段:事件到达目标元素,执行事件处理函数。
  • **冒泡阶段

**:从目标回到祖先,允许祖先元素处理事件。

2. 事件处理方法

  • HTML 属性:在 HTML 标签中直接定义事件。
<button onclick="handleClick()">Click me</button>
  • DOM 0 级:直接给元素的事件属性赋值。
element.onclick = handleClick;
  • DOM 2 级:使用addEventListener添加事件监听器,支持事件冒泡和捕获。
element.addEventListener("click", handleClick);

3. 阻止事件传播

  • 阻止冒泡event.stopPropagation(),阻止事件向上冒泡。
  • 阻止默认行为event.preventDefault(),阻止默认事件行为。
element.addEventListener("click", function(event) {
    event.stopPropagation(); // 阻止冒泡
    event.preventDefault(); // 阻止默认行为
});

4. 事件委托

  • 定义:将事件监听器添加到父元素,通过检查event.target判断事件目标,减少事件监听器数量。
  • 优势:提升性能,减少内存使用。
parentElement.addEventListener("click", event => {
    if (event.target.matches("li")) {
        console.log("LI clicked");
    }
});

八、JavaScript 事件循环

1. 执行栈

  • LIFO 结构:管理函数调用顺序,即后进先出。
  • 作用:控制同步任务的执行顺序。

2. 事件循环步骤

  • 执行同步代码:所有同步任务都在主线程上执行,形成一个执行栈。
  • 处理微任务队列:同步任务完成后,处理微任务(Promise 回调、MutationObserver等)。
  • 处理宏任务队列:处理宏任务(setTimeout,setInterval,I/O回调等)。

3. 宏任务和微任务

  • 宏任务setTimeout,setInterval,I/O,UI Rendering
  • 微任务Promise.then,MutationObserver
console.log("start");

setTimeout(() => {
    console.log("setTimeout");
}, 0);

Promise.resolve().then(() => {
    console.log("promise");
});

console.log("end");

// 输出顺序: start, end, promise, setTimeout

4. 异步任务处理

  • 宏任务:常用于计时器、异步 I/O 操作。
  • 微任务:用于立即执行的异步任务。
setTimeout(() => console.log("Timer"), 0);
Promise.resolve().then(() => console.log("Promise"));