异步编程
异步编程体系 JS 是 单线程 + 事件循环,所有耗时操作丢给浏览器 / Node 底层多线程处理,完成后把回调推入 任务队列,主线程同步代码执行完再取队列执行。所有异步方案,全部基于 回调函数入队执行 这套底层机制搭建。 回调函数模式 回调函数模式是 JS 异步编程 最原始、最通用 的实现方式,所有更高层的异步方案本质都是 对回调的封装。 核心逻辑 异步操作执行完成后,调用预先传入的回调函数来传递结果,通常遵循 错误优先 的约定(Node.js 生态的统一规范)。 错误优先:第一个参数永远是 错误对象,成功时 error 为 null,后续为结果。 错误优先回调成功 / 失败双回调123456789// Node 文件读取 APIfs.readFile("./a.txt", function (err, data) { if (err) { // 单独处理当前层错误 console.error(err); return; } console.log(data.toString());});1...
遍历
数组遍历 全量遍历 forEach:无返回值,仅执行逻辑 遍历数组,对每一项执行回调函数,无返回值,除非抛出错误否则无法中断遍历。 arr.forEach(callback(currentValue, index, array), thisArg) 参数列表 参数 说明 currentValue 当前遍历的元素 index 当前元素索引(可选) array 原数组本身(可选) thisArg 指定回调内的this指向(可选) 调用示例 1234567891011121314151617const fruits = ["苹果", "香蕉", "橙子"];const context = { prefix: "我喜欢的水果:", printFruit: function (name) { console.log(this.prefix + name); },};fruits.forEach(function (current...
垃圾回收
内存泄露 程序在运行过程中,已经不再需要使用的内存,没有被操作系统或垃圾回收机制正确释放,导致 可用内存持续减少 的现象即 内存泄露。 内存泄露的场景 意外的全局变量 12345678910function leak() { // 没有 var/let/const,直接赋值 leakedVar = "这个变量挂在了 window 上"; // 在非严格模式下,函数内部的 this 指向 window this.anotherLeak = "我也是全局的";}leak();// leakedVar 和 window.anotherLeak 永远无法回收,直到页面刷新 使用 use strict 严格模式,它会禁止自动创建全局变量。 隐式全局变量:在非严格模式下,直接给一个未声明的变量赋值,JS 不会报错,会自动把这个变量挂载到全局对象上,变成一个全局变量。 被遗忘的定时器、事件监听器 12345678910const btn = document.querySelector("#btn"...
事件循环
JavaScript 设计为单线程的原因 JavaScript 在1995年诞生时就是作为浏览器脚本,让网页拥有交互能力。 如果允许多线程操作 DOM,需要引入 锁机制,但早期网页只需要简单的表单验证和动画,从简单、安全的角度考虑,JS被设计成了单线程,从根源上避免了 DOM 操作可能产生的并发冲突。 Java 和 JavaScript 语言毫无关系,只是为了商业营销而改名。 WebWorker 拥有独立线程,但是不能访问 DOM,DOM 操作必须限制在主线程。 DOM 和 BOMDOM(文档对象模型) 提供操作文档节点的API,document 是 DOM 的根节点。 BOM(浏览器对象模型) 提供与浏览器窗口交互的API,window 是 BOM 的根结点。 为什么需要任务队列 JavaScript 的 异步API 是由宿主环境提供的,定时器、文件读写等异步操作都交给浏览器底层线程处理,它们的回调不能立刻执行,必须先存起来,存放容器就是 任务队列。 JS 采用 非抢占式调度,不允许中途打断正在执行的同步代码;一旦允许随时插入回调,执行顺序不可预测,会产生大量难以复现的 ...
闭包
闭包的定义 如果一个内层函数访问了外层函数作用域里的变量,那么即使外层函数执行完销毁了,内层函数依然能访问到当初那些外层变量,这个 内层函数 + 被它捕获的外层变量 的集合就叫做 闭包。 闭包不是特意创造的功能。在 ES 标准里,没有单独定义闭包这个语法,只是定义了词法作用域和函数的传递规则,闭包是实现这些规则时的自然而然的产物:如果一个函数被拿到它定义的作用域之外执行,而它又需要访问定义时父作用域的变量,JS 引擎就必须保留这些外层变量,不能随着外层函数执行完就销毁,否则函数在外面执行的时候就找不到变量了。 只要一个语言支持满足以下两个条件的函数,就可以认为支持闭包: 函数可以作为参数、返回值传递,也可以赋值给变量。 函数可以捕获定义时所在作用域的变量,哪怕原作用域已经销毁,这些被捕获的变量依然可以被访问。 ECMAScript 与 JavaScriptES 是 ECMAScript 的缩写,是由国际标准化组织 ECMA 国际 制定的脚本语言的通用规范标准,它不绑定任何具体的宿主环境,只规定脚本语言最核心的语法、特性、规则。 JavaScript 是 ES 规范 最知名...




