事件循环
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 规范 最知名...
模块
在 JavaScript 中,模块 的作用是:将代码分割成 独立、可复用 的文件,每个文件拥有独立私有作用域,通过导出、导入实现文件间代码复用。 主要有两大规范:CommonJS(CJS,Node.js 旧规范)、ES Module(ESM,ES6 新标准)。 CommonJS CommonJS 中,模块的导出本质是给 module.exports 对象赋值,所有需要对外暴露的内容都挂载在这个对象上。 CommonJS 是 Node.js 默认模块规范,浏览器不原生支持,运行时同步加载。 导出和导入 1. 导出单个内容(函数、对象、变量、类都可以) 12345678910// utils.js 导出一个工具函数function add(a, b) { return a + b;}// 直接把整个模块导出为add函数module.exports = add;// 导入的add就是utils.js导出的函数const add = require("./utils.js");console.log(add(1, 2)); // 3 2. 导出...







