当前位置: 首页 > news >正文

wordpress 时间设置优化排名软件

wordpress 时间设置,优化排名软件,wordpress正文标题样式,网站图片分辨率尺寸JavaScript 前端知识体系 #x1f4cc; 说明#xff1a;本大纲从基础到高级、从语法到应用、从面试到实战#xff0c;分层级讲解 JavaScript 的核心内容。 一、JavaScript 基础语法 1.1 基本概念 1.1.1 JavaScript 的发展史与用途 1. 发展简史 1995 年#xff1a;JavaS…JavaScript 前端知识体系 说明本大纲从基础到高级、从语法到应用、从面试到实战分层级讲解 JavaScript 的核心内容。 一、JavaScript 基础语法 1.1 基本概念 1.1.1 JavaScript 的发展史与用途 1. 发展简史 1995 年JavaScript 由 Netscape 工程师 Brendan Eich 在 10 天 内创建最初叫 LiveScript后更名为 JavaScript。早期用途仅用于网页中的简单表单校验和交互动画。1997 年被 ECMA 国际标准化组织采纳形成 ECMAScript 标准。2009 年Node.js 横空出世JS 从浏览器进入服务端。2015 年ES6ECMAScript 2015发布成为 JS 的重大飞跃。 2. 现代用途 JavaScript 已不再只是“网页脚本语言”现在几乎无所不能 浏览器交互开发HTMLCSSJSWeb 应用开发React/Vue/Angular服务端开发Node.js移动端开发React Native桌面应用开发Electron游戏开发Pixi.js、Three.js自动化测试、爬虫、AI 前端可视化等 一句话总结JS 是一门“浏览器起家、全栈统治、无处不在”的语言。 1.1.2 浏览器中的 JS 与 Node.js 的区别 特性浏览器中的 JSNode.js运行环境浏览器Chrome、Firefox 等服务端基于 V8 引擎核心目标实现用户交互、DOM 操作搭建 Web 服务、处理后端逻辑可访问的 APIDOM、BOMwindow、document等文件系统fs、网络模块http模块系统ES ModuleES6后支持CommonJS全局对象windowglobal适合应用场景网页开发、浏览器插件接口服务、工具脚本、构建工具等 一句话记忆浏览器 JS 用于“看得见的交互”Node.js 用于“看不见的服务”。 1.1.3 动态类型语言 vs 静态类型语言 1. 类型系统简介 类型变量可以表示的数据类型例如字符串、数字、布尔值等。类型系统语言如何检测、限制这些数据类型的规则体系。 2. 对比分析 特性动态类型语言如 JS静态类型语言如 Java、C声明变量不需指定类型运行时才知道声明时必须指定类型类型检查在运行时进行在编译阶段进行灵活性高变量可变类型低但可提升可靠性出错时间点运行时才报错编译时就能发现类型错误开发体验快速开发适合原型迭代安全稳定适合大型项目 3. 示例对比 // JS - 动态类型 let x 10; x hello; // 合法x 类型变为 string // Java - 静态类型 int x 10; x hello; // ❌ 报错类型不匹配总结一句话JS 是“你想放什么我都装”Java 是“你不给我指定我不干活”。 1.2 数据类型 JavaScript 中的数据类型分为两大类原始类型Primitive Type 和 引用类型Reference Type。 1.2.1 原始类型7 种 原始类型是不可变值每个变量直接存储值本身保存在栈内存中。 类型示例值说明Stringhello表示文本Number42, 3.14, NaN所有数字包含整数和浮点数Booleantrue, false逻辑值Undefinedundefined未赋值变量的默认值Nullnull表示“无值”SymbolSymbol(id)创建独一无二的标识符ES6BigInt12345678901234567890n表示任意精度整数ES11 示例 let name Alice; // String let age 30; // Number let isAdmin true; // Boolean let user; // Undefined let empty null; // Null let key Symbol(id); // Symbol let bigNumber 123456789012345678901234567890n; // BigInt注意typeof null object 是历史遗留 bug不代表 null 是引用类型 1.2.2 引用类型常见 5 类 引用类型是可变对象变量保存的是指向值的地址引用保存在堆内存中。 类型示例特点Object{name: Tom}万物皆对象的基础类型Array[1, 2, 3]有序集合索引访问Functionfunction() {}可调用对象函数是一等公民Datenew Date()日期对象RegExp/\d/正则表达式对象 示例 let person { name: Tom, age: 25 }; // Object let numbers [1, 2, 3]; // Array let greet function() { console.log(Hi); }; // Function let now new Date(); // Date let pattern /\d/; // RegExp1.2.3 原始类型 vs 引用类型 对比总结 特性原始类型引用类型存储方式栈内存值拷贝堆内存引用拷贝指针是否可变不可变每次修改都创建新值可变修改对象本身比较方式值比较引用地址比较复制行为复制值复制引用多个变量指向同一对象 示例比较 let a 100; let b a; b 200; console.log(a); // 100原始类型值独立let obj1 { x: 1 }; let obj2 obj1; obj2.x 99; console.log(obj1.x); // 99引用类型地址共享一句话总结原始类型像“复制粘贴”引用类型像“共享文件夹”。 1.3 变量声明 1.3.1 var、let、const 的区别 特性varletconst声明方式ES5函数级作用域ES6块级作用域ES6块级作用域变量提升✅ 有提升值为 undefined✅ 有提升但不初始化✅ 有提升但不初始化允许重复声明✅ 允许❌ 报错❌ 报错可重新赋值✅ 可以✅ 可以❌ 不可重新赋值是否必须初始化❌ 不需要❌ 不需要✅ 必须初始化 示例 // var console.log(a); // undefined已提升 var a 10;// let console.log(b); // ReferenceError暂时性死区 let b 20;// const const c 30; c 40; // ❌ 报错不能重新赋值记忆口诀var 会提升let 会保护const 定值不可改。 1.3.2 作用域与变量提升Hoisting 函数作用域Function Scopevar 声明的变量只在函数内部有效。块级作用域Block Scopelet 和 const 声明的变量只在当前代码块 {} 内有效。 function test() {if (true) {var x 10;let y 20;}console.log(x); // ✅ 输出 10console.log(y); // ❌ 报错 }变量提升HoistingJavaScript 在运行前会“预处理”变量和函数声明使它们“看起来”被提升到作用域顶部。 console.log(a); // undefined var a 5;1.4 运算符与表达式 1.4.1 算术、比较、逻辑运算符 算术运算符 - * / % **比较运算符 ! !逻辑运算符 || ! 2 ** 3 // 8幂运算 3 2 // true true false // false1.4.2 其他运算符 三元运算符条件 ? 值1 : 值2 let result score 60 ? 及格 : 不及格;位运算符 | ^ ~ 适用于底层优化如权限控制、性能压缩空值合并运算符??仅在左值为 null 或 undefined 时使用右值。 let name userName ?? 默认用户;1.5 流程控制 1.5.1 条件判断 if…else if (score 90) {console.log(优秀); } else if (score 60) {console.log(及格); } else {console.log(不及格); }switch…case let color green; switch (color) {case red:console.log(红色);break;case green:console.log(绿色);break;default:console.log(未知颜色); }1.5.2 循环结构 for 循环 for (let i 0; i 3; i) {console.log(i); }while / do…while let i 0; while (i 3) {console.log(i);i; }do {console.log(i);i--; } while (i 0);for…in遍历对象的键 let obj { a: 1, b: 2 }; for (let key in obj) {console.log(key); // a, b }for…of遍历可迭代对象的值如数组、字符串 for (let value of [10, 20, 30]) {console.log(value); // 10, 20, 30 }记忆总结 for...in 用来遍历“对象键名”for...of 用来遍历“数组值”。 二、函数与作用域 2.1 函数定义方式 2.1.1 函数声明Function Declaration function sayHi(name) {return Hello, ${name}; }✅ 支持提升可以在函数声明之前调用✅ 语义清晰适合通用工具函数 函数体内 this 指向调用者 greet(); // ✅ 输出 Hi there!function greet() {console.log(Hi there!); }2.1.2 函数表达式Function Expression const sayHi function(name) {return Hello, ${name}; };❌ 不支持提升调用必须在定义之后✅ 更灵活可作为参数传递、闭包使用✅ 命名 or 匿名支持匿名函数 // 报错Cannot access greet before initialization greet();const greet function () {console.log(Hello); };2.1.3 箭头函数Arrow Function const sayHi (name) {return Hello, ${name}; };✅ 语法简洁❗ 没有自己的 this、arguments❌ 不能当构造函数使用 简写形式单参数、单表达式可省略括号与 return const double x x * 2;this 对比示例 const obj {normal: function() {console.log(this); // 指向 obj},arrow: () {console.log(this); // 指向定义时外部的 this可能是 window 或 undefined} };一图记忆 类型是否提升是否有 this是否能 new是否简洁函数声明✅✅✅❌函数表达式❌✅✅❌箭头函数❌❌继承❌✅✅✅ 2.2 作用域与闭包 2.2.1 词法作用域Lexical Scope 定义词法作用域是指变量的作用范围由代码书写位置决定而非函数的调用方式。 function outer() {const a 10;function inner() {console.log(a); // 可以访问 a}inner(); } outer();函数定义在哪里就决定了它能访问哪些变量。✅ 内部函数可以访问其外部函数作用域中的变量这就是闭包的基础。 记忆口诀作用域查找看“定义位置”不是“调用位置”。 2.2.2 闭包原理与应用场景 什么是闭包 闭包Closure是函数与其词法环境的组合。当函数在其定义的作用域外被调用时它仍然能够记住并访问其定义时的作用域链。 function createCounter() {let count 0;return function () {count;return count;}; }const counter createCounter(); console.log(counter()); // 1 console.log(counter()); // 2count 没有被销毁因为返回的函数一直引用它这就是闭包。 JS 的函数是一等对象可以被返回、赋值、传参而闭包能让这些函数带上“记忆”。 闭包的常见应用场景 场景示例数据私有封装内部变量不暴露到全局作用域函数工厂动态生成具有“私有数据”的函数防抖节流利用闭包保存定时器引用等状态记忆函数缓存函数执行结果Memoization // 数据私有模拟私有变量 function Secret() {let secret 密码123;return {get: () secret,set: (val) secret val}; } const s Secret(); console.log(s.get()); // 密码123一句话总结闭包 函数 定义时的作用域链是 JS 中实现“私有状态”和“记忆能力”的核心机制。 2.3 this 指向与 call/apply/bind 2.3.1 this 在不同上下文的指向规则 this 在 JavaScript 中非常灵活它的指向是动态的依赖于函数的调用方式。我们可以将它分为几种主要的调用方式进行分类讲解。 一、隐式绑定Implicit Binding 隐式绑定指的是 在对象的方法中调用函数时this 指向调用该方法的对象。 const person {name: Alice,greet() {console.log(this.name);} }; person.greet(); // Alice在这个例子中this 指向 person 对象。 二、显式绑定Explicit Binding 显式绑定是通过 call、apply 和 bind 等方法显式地指定 this 的指向。 call()立即调用函数传入 this 指定的对象和后续参数。 function greet() {console.log(Hello, ${this.name}); } const person { name: Bob }; greet.call(person); // Hello, Bobapply()类似 call()但接收一个数组作为参数。 greet.apply(person); // Hello, Bobbind()返回一个新函数绑定了 this但不立即执行。 const boundGreet greet.bind(person); boundGreet(); // Hello, Bob总结call 和 apply 立即执行而 bind 返回一个新的函数。 三、默认绑定Default Binding 当函数被直接调用例如普通函数调用时this 的默认指向规则会根据执行环境有所不同 在 非严格模式下this 会指向全局对象浏览器中是 windowNode 中是 global。在 严格模式下this 为 undefined。 function greet() {console.log(this); }greet(); // 在非严格模式下指向 window严格模式下指向 undefined四、构造函数绑定Constructor Binding 当函数作为构造函数通过 new 关键字调用时this 会指向新创建的实例对象。 function Person(name) {this.name name; }const person1 new Person(Alice); console.log(person1.name); // Alicenew 关键字使得 this 指向新创建的实例对象。 五、箭头函数Arrow Function 箭头函数没有自己的 this它会继承外层上下文的 this。也就是说箭头函数的 this 是在定义时就确定的而不是在调用时确定。 const obj {name: Alice,greet() {const arrowFunc () {console.log(this.name);};arrowFunc(); // Alice} };obj.greet(); // AlicearrowFunc 的 this 指向的是外部的 greet 方法中的 this即 obj。 总结 调用方式this 指向隐式绑定调用方法的对象显式绑定call、apply、bind 参数指定的对象默认绑定非严格模式下为 window严格模式下为 undefined构造函数绑定新创建的对象实例箭头函数继承外部作用域的 this 2.3.2 手动改变 this 指向的方法 有三个方法可以手动改变函数内部的 this 指向 1call() 立即调用函数传入第一个参数作为 this后续参数依次传给函数本体。 function greet(who) {console.log(Hello, ${who}, from ${this.name}); } const person { name: Alice }; greet.call(person, Bob); // Hello, Bob, from Alice2apply() 与 call 类似但参数必须用数组传入 greet.apply(person, [Charlie]); // Hello, Charlie, from Alice3bind() 不会立即调用而是返回一个新的函数绑定了 this。 const boundGreet greet.bind(person, Diana); boundGreet(); // Hello, Diana, from Alice对比总结 方法是否立即执行参数传递方式返回值call✅ 是普通参数列表函数执行结果apply✅ 是参数数组函数执行结果bind❌ 否参数列表可预设新函数 记忆口诀 call 马上叫、apply 数组搞、bind 等你叫。 三、对象与原型链 3.1 对象创建与属性操作 3.1.1 对象的创建方式 字面量法 使用大括号 {} 直接定义对象简单直观。 const person {name: Alice,age: 30 };构造函数法 使用 new Object() 或通过自定义构造函数创建对象。 const person new Object(); person.name Bob; person.age 25;Object.create() 使用指定的原型对象创建一个新对象适用于原型链继承。 const personProto {greet() {console.log(Hello, ${this.name});} };const person Object.create(personProto); person.name Charlie; person.greet(); // Hello, Charlieclass 关键字 使用 ES6 中的 class 语法创建对象及其构造函数。 class Person {constructor(name, age) {this.name name;this.age age;} } const person new Person(David, 28);3.1.2 属性描述符与 Object.defineProperty() 属性描述符定义了对象属性的特性如是否可写、可枚举等。 数据描述符包含 value 和 writable是否可修改。访问器描述符包含 get 和 set。 Object.defineProperty() 方法允许你直接设置属性的描述符并能够控制属性的行为例如是否能修改、是否能枚举等。 const person {}; Object.defineProperty(person, name, {value: Eve,writable: false, // 不可修改enumerable: true, // 可枚举configurable: true // 可配置 });console.log(person.name); // Eve person.name John; // 不会修改 console.log(person.name); // Evewritable: false 使得 name 属性不可修改。configurable: false 防止删除该属性或修改其特性。 3.2 原型与原型链 3.2.1 __proto__ vs prototype prototype 每个函数对象都有一个 prototype 属性指向该函数的原型对象。构造函数的实例会继承该原型对象上的属性和方法。 function Person(name) {this.name name; }const person new Person(Alice); console.log(person.__proto__ Person.prototype); // true__proto__ __proto__ 是每个对象的内部属性指向该对象的构造函数的原型对象。它指示了对象的原型链的“父级”。 const obj {}; console.log(obj.__proto__ Object.prototype); // trueprototype 是函数的属性而 __proto__ 是对象的属性。 3.2.2 原型链查找机制 当访问对象的属性时JS 引擎会先在对象自身查找如果没有找到再沿着原型链向上查找直到找到该属性或到达 null 为止。 每个对象都有一个 __proto__ 属性它指向该对象的构造函数的原型对象。原型对象也有 __proto__形成一个链条最终链条的尽头是 Object.prototype它的 __proto__ 为 null。 const obj { name: Alice }; console.log(obj.name); // Alice console.log(obj.toString()); // 调用 Object.prototype.toStringobj 没有 toString 方法它会向原型链上的 Object.prototype 查找 toString 方法。 3.3 继承方式 3.3.1 ES5 原型继承 在 ES5 中原型继承是通过构造函数和 prototype 属性实现的。基本的继承方式是通过让子类的 prototype 指向父类的 prototype。 function Animal(name) {this.name name; }Animal.prototype.sayHello function() {console.log(Hello, I am a ${this.name}); };function Dog(name) {Animal.call(this, name); // 继承属性 }Dog.prototype Object.create(Animal.prototype); // 继承方法 Dog.prototype.constructor Dog; // 修复构造函数指向const dog new Dog(Buddy); dog.sayHello(); // Hello, I am a BuddyObject.create() 用于创建一个新的对象将原型链指向父类的原型对象从而实现继承。 3.3.2 组合继承 组合继承又叫伪经典继承是 构造函数继承 和 原型继承 的组合它解决了原型继承的缺点子类会继承父类的所有实例属性但每个子类实例都会重复父类的实例属性。 function Animal(name) {this.name name; }Animal.prototype.sayHello function() {console.log(Hello, I am a ${this.name}); };function Dog(name, breed) {Animal.call(this, name); // 继承实例属性this.breed breed; }Dog.prototype new Animal(); // 继承方法 Dog.prototype.constructor Dog;const dog new Dog(Buddy, Golden Retriever); dog.sayHello(); // Hello, I am a Buddy console.log(dog.breed); // Golden Retriever缺点构造函数 Animal.call(this) 被调用了两次。new Animal() 会创建父类的实例并将父类的属性赋给子类原型。 3.3.3 类似寄生继承的方式 寄生继承 是通过 借用构造函数 的方式继承父类的属性但不改变原型链。 function Animal(name) {this.name name; }Animal.prototype.sayHello function() {console.log(Hello, I am a ${this.name}); };function Dog(name, breed) {Animal.call(this, name); // 继承属性this.breed breed; }Dog.prototype Object.create(Animal.prototype); // 继承方法 Dog.prototype.constructor Dog;const dog new Dog(Buddy, Golden Retriever); dog.sayHello(); // Hello, I am a Buddy console.log(dog.breed); // Golden Retriever这个方式在继承父类方法时依然保持了父类原型链的正确性解决了构造函数重复调用的问题。 3.3.4 寄生组合继承 寄生组合继承parasitic combination inheritance是一种优化的方式它结合了 寄生继承 和 组合继承 的优点。通过 Object.create() 继承父类的方法并通过构造函数继承父类的实例属性避免了重复调用父类构造函数。 function Animal(name) {this.name name; }Animal.prototype.sayHello function() {console.log(Hello, I am a ${this.name}); };function Dog(name, breed) {Animal.call(this, name); // 继承属性this.breed breed; }// 使用寄生组合继承来避免重复调用父类构造函数 Dog.prototype Object.create(Animal.prototype); Dog.prototype.constructor Dog;const dog new Dog(Buddy, Golden Retriever); dog.sayHello(); // Hello, I am a Buddy console.log(dog.breed); // Golden Retriever优化点只调用一次父类的构造函数通过 Object.create() 来继承父类的原型方法避免了组合继承的性能问题。 3.3.5 ES6 class 继承 (extends 与 super) ES6 引入了 class 和 extends 语法使得继承更加简洁和直观。super 用于调用父类的构造函数或方法。 class Animal {constructor(name) {this.name name;}sayHello() {console.log(Hello, I am a ${this.name});} }class Dog extends Animal {constructor(name, breed) {super(name); // 调用父类构造函数this.breed breed;}bark() {console.log(Woof!);} }const dog new Dog(Buddy, Golden Retriever); dog.sayHello(); // Hello, I am a Buddy dog.bark(); // Woof!extends 用于实现继承。super 用于调用父类的构造函数或方法。 3.3 总结 继承方式描述优缺点原型继承通过设置子类原型为父类原型的实例来实现继承缺点父类实例属性会被所有子类实例共享组合继承结合构造函数继承和原型继承缺点构造函数被调用两次寄生继承通过借用构造函数继承父类实例属性不改变原型适用于不需要创建新对象的场景寄生组合继承结合了寄生继承与组合继承的优点优化了性能解决了组合继承的缺点避免了重复调用构造函数ES6 class使用 class 和 extends 语法简化继承语法简洁易于理解但仍然是基于原型链的继承 四、数组与内置对象 4.1 数组操作 4.1.1 创建与转换 方法返回值是否修改原数组作用Array.of(...items)新数组包含所有参数否创建一个包含所有参数的数组Array.from(obj)新数组类数组转数组否将类数组或可迭代对象转换为数组arr.toString()字符串元素用逗号连接否将数组元素转换为字符串用逗号分隔arr.join(sep)字符串自定义分隔符否将数组元素连接成字符串使用指定的分隔符 4.1.2 增删元素 方法返回值是否修改原数组作用push(...items)新长度是在数组末尾添加一个或多个元素pop()被删除的元素是删除并返回数组的最后一个元素unshift(...items)新长度是在数组开头添加一个或多个元素shift()被删除的元素是删除并返回数组的第一个元素splice(start, del, ...items)被删除的元素数组是从指定位置删除指定数量的元素并可以插入新元素slice(start, end)新数组部分元素否返回数组的一个浅拷贝部分 4.1.3 查找与过滤 方法返回值是否修改原数组作用indexOf(item)首个匹配索引-1 表示不存在否查找元素首次出现的位置lastIndexOf(item)最后匹配索引-1 表示不存在否查找元素最后一次出现的位置includes(item)布尔值是否包含否判断数组是否包含某个元素find(fn)首个匹配元素undefined 表示不存在否查找并返回第一个满足条件的元素findIndex(fn)首个匹配索引-1 表示不存在否查找并返回第一个满足条件的元素索引filter(fn)新数组所有匹配元素否返回一个包含所有满足条件元素的新数组 4.1.4 遍历与转换 方法返回值是否修改原数组作用forEach(fn)undefined否但可修改元素遍历数组执行给定的函数适用于副作用操作map(fn)新数组每个元素处理后否返回一个新的数组每个元素经过给定函数处理flat(depth)新数组扁平化后否将嵌套的数组结构“拉平”至指定深度flatMap(fn)新数组先 map 再 flat否先对数组进行 map 操作再进行扁平化 4.1.5 排序与反转 方法返回值是否修改原数组作用sort(fn)原数组排序后是对数组进行排序默认按字符顺序排列reverse()原数组反转后是将数组元素的顺序颠倒 4.1.6 合并与拆分 方法返回值是否修改原数组作用concat(...arrays)新数组合并后否合并多个数组或值到一个新数组split(sep)字符串 → 数组否操作字符串将字符串分割为数组join(sep)数组 → 字符串否将数组元素连接成一个字符串使用指定的分隔符 4.1.7 归约方法 方法返回值是否修改原数组作用reduce(fn, init)累计值否对数组元素执行累加操作返回累计值reduceRight(fn, init)累计值从右到左否从右到左对数组元素执行累加操作返回累计值 4.1.8 判定方法 方法返回值是否修改原数组作用every(fn)布尔值所有元素满足否判断数组中的每个元素是否都满足条件some(fn)布尔值至少一个满足否判断数组中是否至少有一个元素满足条件isArray(value)布尔值是否为数组否静态方法判断给定值是否为数组 4.1.9 其他方法 方法返回值是否修改原数组作用fill(value, start, end)原数组填充后是用指定的值填充数组的某部分元素copyWithin(target, start, end)原数组复制后是将数组中的一部分复制到同一数组的指定位置entries()迭代器索引-值对否返回一个数组的遍历器对象包含索引和对应值keys()迭代器索引否返回一个包含数组索引的遍历器对象values()迭代器值否返回一个包含数组值的遍历器对象 记忆技巧 修改原数组的方法 push/pop/unshift/shift/splice/sort/reverse/fill/copyWithin 口诀增删改查排序反转填充复制返回新数组的方法 slice/map/filter/concat/flat/flatMap 口诀切片映射过滤合并扁平化归约与判定 reduce/every/some/find/findIndex/includes 口诀累计判定查找包含 4.2 常用内置对象 4.2.1 String 对象 1. 字符操作 方法返回值作用charAt(index)字符返回指定位置的字符charCodeAt(index)数字返回指定位置字符的 Unicode 编码codePointAt(index)数字返回指定位置字符的 Unicode 代码点fromCharCode(...codes)字符串从 Unicode 编码返回字符fromCodePoint(...codePoints)字符串从 Unicode 代码点返回字符 2. 查找与替换 方法返回值作用includes(searchString)布尔值判断字符串是否包含指定的子串indexOf(searchValue)索引返回子串首次出现的位置lastIndexOf(searchValue)索引返回子串最后一次出现的位置match(regexp)数组匹配正则表达式并返回结果replace(searchValue, newValue)新字符串替换匹配的子字符串 3. 大小写转换 方法返回值作用toLowerCase()小写字符串返回将所有字符转换为小写的新字符串toUpperCase()大写字符串返回将所有字符转换为大写的新字符串 4. 切割与连接 方法返回值作用slice(start, end)子字符串返回字符串的一个部分split(separator)数组按照指定分隔符拆分字符串concat(...strings)字符串连接多个字符串并返回新字符串join(sep)字符串数组元素连接为字符串 4.2.2 Date 对象 1. 获取日期与时间 方法返回值作用getFullYear()年份返回完整的年份4位getMonth()月份返回月份0-11getDate()日期返回一个月中的日期1-31getDay()星期几返回星期几0-60为星期天getHours()小时返回小时0-23getMinutes()分钟返回分钟0-59getSeconds()秒数返回秒数0-59getMilliseconds()毫秒返回毫秒数0-999 2. 设置日期与时间 方法返回值作用setFullYear(year)设置年份设置年份4位setMonth(month)设置月份设置月份0-11setDate(day)设置日期设置日期1-31setHours(hours)设置小时设置小时0-23setMinutes(minutes)设置分钟设置分钟0-59setSeconds(seconds)设置秒数设置秒数0-59setMilliseconds(milliseconds)设置毫秒设置毫秒0-999 4.2.3 Math 对象 1. 数学常用方法 方法返回值作用Math.abs(x)数值返回 x 的绝对值Math.ceil(x)数值返回大于或等于 x 的最小整数Math.floor(x)数值返回小于或等于 x 的最大整数Math.round(x)数值返回四舍五入后的值Math.random()数值返回一个 0 到 1 之间的随机数Math.sqrt(x)数值返回 x 的平方根 2. 极值与范围 方法返回值作用Math.max(...values)数值返回一组数中的最大值Math.min(...values)数值返回一组数中的最小值Math.pow(x, y)数值返回 x 的 y 次方Math.PI数值返回圆周率常量 π 4.2.4 JSON 对象 1. JSON 解析与字符串化 方法返回值作用JSON.parse(text)对象/数组将 JSON 字符串解析为 JavaScript 对象JSON.stringify(value)JSON 字符串将 JavaScript 对象转换为 JSON 字符串 4.2.5 RegExp 对象 1. 正则表达式方法 方法返回值作用test(str)布尔值测试正则表达式是否匹配字符串exec(str)数组返回正则表达式与字符串匹配的结果如果有 五、异步编程与事件机制 5.1 异步基础 5.1.1 同步 vs 异步 同步Synchronous任务按顺序逐行执行前一个任务不完成后一个任务无法开始。异步Asynchronous某些操作可在“等待结果”的同时继续执行其他任务。 示例 console.log(A); setTimeout(() console.log(B), 1000); console.log(C); // 输出顺序A → C → B5.1.2 回调函数与 Callback Hell 回调函数将一个函数作为参数传给另一个函数用于异步任务完成后执行。回调地狱Callback Hell多个嵌套回调导致代码结构混乱、难以维护。 示例 doSomething(function(result1) {doSomethingElse(result1, function(result2) {doThirdThing(result2, function(result3) {console.log(All done!);});}); });5.2 Promise 与 async/await 5.2.1 Promise 构造与链式调用进阶版 Promise 是异步编程的核心机制表示一个可能现在、将来或永不完成的值。状态只能从 pending → fulfilled 或 pending → rejected不可逆。 ✅ 一、创建 Promise 实例 const p new Promise((resolve, reject) {const data getData();if (data) resolve(data);else reject(new Error(获取失败)); });resolve(value)表示成功进入 .then() 分支reject(error)表示失败进入 .catch() 分支 ✅ 二、链式调用then / catch / finally p.then(result {console.log(成功, result);return result !; }).then(modified {console.log(链式处理, modified); }).catch(err {console.error(捕获错误, err); }).finally(() {console.log(无论成功失败都会执行); });.then() 可以返回新值传递给下一个 .then().catch() 捕获任意前面出现的错误.finally() 不处理值仅用于收尾动作如关闭 loading ✅ 三、错误传播机制 若 .then() 中抛出错误会直接被后面的 .catch() 捕获。 p.then(() {throw new Error(出错了); }).catch(err {console.log(捕获到错误, err.message); });✅ 四、Promise 嵌套与避免回调地狱 getUserInfo().then(user {return getPostsByUser(user.id); }).then(posts {return getCommentsForPost(posts[0].id); });通过链式结构代替回调嵌套实现逻辑扁平化若返回的是一个新的 Promise则自动等待其执行完成 ✅ 五、常见错误使用案例警示 // ⚠️ 不要这样写 p.then(res {doSomething(res, function(result) {// 回调地狱又来了}); });应改写为 p.then(res doSomethingAsync(res)).then(next console.log(next));非常好Promise 除了构造函数和链式调用外还有一组非常实用的静态方法类方法适用于多个异步任务的管理与控制。以下是完整补充按照清晰的结构归类呈现 5.2.2 Promise 所有方法汇总 ✅ 一、构造函数实例方法 方法作用特点new Promise(fn)创建一个新的 Promise 实例传入 resolve 和 reject 两个函数参数.then(onFulfilled)注册成功回调函数支持链式调用.catch(onRejected)注册失败回调函数是 .then(null, onRejected) 的语法糖.finally(fn)无论成功/失败都会执行不影响返回值传递 ✅ 二、静态方法类方法 1. Promise.resolve(value) 返回一个状态为 fulfilled 的 Promise如果传入的是一个 Promise会直接返回 Promise.resolve(42).then(console.log); // 422. Promise.reject(error) 返回一个状态为 rejected 的 Promise通常用于封装异常 Promise.reject(失败).catch(console.error); // 失败3. Promise.all([p1, p2, …]) 等待所有 Promise 成功才 resolve否则立即 reject返回值是所有结果的数组按顺序 Promise.all([p1, p2]).then(([r1, r2]) {console.log(r1, r2); });常用于并发请求必须都成功 4. Promise.race([p1, p2, …]) 谁先完成成功或失败就采用谁的结果竞速场景如加载动画 vs 请求超时 Promise.race([fetchData(),timeoutPromise(3000) ]).then(console.log).catch(console.error);5. Promise.allSettled([p1, p2, …]) 等待所有 Promise 都结束无论成功或失败每一项返回 { status, value } 或 { status, reason } Promise.allSettled([p1, p2]).then(results {results.forEach(r console.log(r.status)); });常用于统计、批处理不能因为一个失败而中断 6. Promise.any([p1, p2, …]) 谁先成功就 resolve全部失败才 rejectES2021 新增 Promise.any([Promise.reject(失败1),Promise.resolve(成功),Promise.reject(失败2) ]).then(console.log); // 输出成功常用于只需一个成功即可如镜像 CDN 请求 ✅ 三、对比总结 方法成功策略失败策略典型应用Promise.all全部成功任意失败立即中止并行任务且都要成功Promise.race谁先返回谁先返回超时控制Promise.allSettled不关心不关心全部结果分析Promise.any任意一个成功即可全部失败才失败多镜像请求、降级处理 ✨ 小贴士手写模拟 Promise.all核心思维训练 function promiseAll(promises) {return new Promise((resolve, reject) {let result [], count 0;promises.forEach((p, i) {Promise.resolve(p).then(val {result[i] val;count;if (count promises.length) resolve(result);}).catch(reject);});}); }5.2.3 async/await async 声明函数返回一个 Promise。await 暂停异步函数执行等待 Promise 结果。 示例 async function fetchData() {try {const data await getData();console.log(data);} catch (error) {console.error(Error:, error);} }5.3 事件循环机制Event Loop 5.3.1 宏任务 vs 微任务 类型示例执行时机宏任务setTimeout、setInterval、I/O、setImmediateNode每轮事件循环开始时调度微任务Promise.then、queueMicrotask、MutationObserver浏览器当前宏任务执行完立即执行所有微任务 执行顺序示例 console.log(start);setTimeout(() console.log(setTimeout), 0); Promise.resolve().then(() console.log(promise)); queueMicrotask(() console.log(microtask)); console.log(end);// 输出start → end → promise → microtask → setTimeout5.3.2 浏览器中的事件循环流程 执行全局同步代码主线程 → 调用栈执行所有微任务队列执行一个宏任务队列中的任务重复步骤 2 → 3直到所有任务完成 5.3.3 Node.js 中的事件循环阶段 Node.js 的事件循环更复杂包含 6 个阶段基于 libuv 阶段描述timers执行 setTimeout、setInterval 回调pending callbacks执行一些系统操作的回调如 TCP 错误idle/prepare内部使用poll处理 I/O 事件如果没有则可能进入 check 阶段或等待check执行 setImmediate() 的回调close callbacks执行如 socket.on(close, fn) 等关闭回调 ✅ 每个阶段之间都会清空微任务队列process.nextTick Promise。 微任务优先级 process.nextTick Promise.then 宏任务setTimeout、setImmediateNode 示例 setTimeout(() console.log(timeout), 0); setImmediate(() console.log(immediate));Promise.resolve().then(() console.log(promise)); process.nextTick(() console.log(nextTick));// 输出顺序nextTick → promise → timeout/immediate取决于系统✅ 总结执行顺序记忆口诀 浏览器中同步 → 微任务 → 宏任务Node.js 中同步 → nextTick → Promise → 各阶段宏任务 提示Node.js 中的 setImmediate 可能比 setTimeout(fn, 0) 更快执行但不保证一致顺序。 六、DOM 与 BOM 操作 6.1 DOM 基础全面分类 6.1.1 节点获取与遍历 方法描述返回类型getElementById(id)根据 ID 获取节点单个元素getElementsByClassName(class)根据类名获取类数组getElementsByTagName(tag)根据标签名获取类数组querySelector(selector)CSS 选择器获取首个匹配节点单个元素querySelectorAll(selector)CSS 选择器获取全部匹配节点NodeList类数组parentNode / childNodes / nextSiblingDOM 树节点关系遍历节点对象 6.1.2 节点创建、插入、删除、克隆 操作方法示例创建元素createElement(tag)let div document.createElement(div)插入appendChild()、append()、insertBefore()parent.appendChild(child)删除removeChild()、remove()parent.removeChild(el)替换replaceChild(newEl, oldEl)替换节点克隆cloneNode(true)复制节点 6.1.3 节点内容与属性操作 操作方法 / 属性示例获取/设置文本innerText / textContentel.textContent Hello获取/设置 HTMLinnerHTMLel.innerHTML bHi/b获取/设置属性getAttribute() / setAttribute()el.setAttribute(href, #)移除属性removeAttribute()el.removeAttribute(title)操作类名classList.add/remove/toggle/containsel.classList.toggle(show)操作样式style.propertyel.style.color red 6.1.4 元素位置与尺寸获取 属性 / 方法描述示例offsetTop / offsetLeft元素相对 offsetParent 的偏移el.offsetTopoffsetWidth / offsetHeight包含 padding 和 borderel.offsetHeightclientWidth / clientHeight包含 padding 不含 borderel.clientWidthscrollTop / scrollLeft滚动距离el.scrollTopgetBoundingClientRect()获取元素相对视口的位置与尺寸el.getBoundingClientRect() 6.1.5 常用事件分类 一鼠标事件 事件名说明click / dblclick点击 / 双击mousedown / mouseup按下 / 弹起mousemove鼠标移动mouseenter / mouseleave进入 / 离开元素不冒泡mouseover / mouseout进入 / 离开冒泡contextmenu右键菜单 二键盘事件 事件名说明keydown键盘按下keyup键盘松开keypress输入字符已废弃 三表单事件 事件名说明submit表单提交change表单值变化如 selectinput输入变化推荐用于 text 输入focus / blur聚焦 / 失焦 四窗口事件 事件名说明load页面加载完成resize窗口尺寸变化scroll页面或元素滚动beforeunload页面关闭前 6.1.6 事件监听与代理 操作示例绑定事件el.addEventListener(click, fn)移除事件el.removeEventListener(click, fn)阻止默认行为event.preventDefault()阻止冒泡event.stopPropagation()事件代理绑定父级判断 e.target list.addEventListener(click, e {if (e.target.tagName LI) {console.log(点击了第, e.target.innerText);} });6.1.7 拖拽与监听移动 功能方法拖拽事件dragstart / dragover / drop鼠标监听移动结合 mousedown、mousemove、mouseup 实现 示例伪代码实现拖动 let isDragging false; el.onmousedown () isDragging true; document.onmousemove (e) {if (isDragging) el.style.left e.clientX px; }; document.onmouseup () isDragging false;6.2 事件模型浏览器 6.2.1 事件传播机制捕获 冒泡 事件传播分为 三个阶段 阶段顺序阶段名称描述①捕获阶段Capture Phase从 window 自顶向下沿着 DOM 树传递到目标元素②目标阶段Target Phase实际目标元素上触发的事件③冒泡阶段Bubble Phase从目标元素沿 DOM 树向上传递回 window 示例 element.addEventListener(click, handler, true); // 第三个参数 true 表示捕获阶段监听 element.addEventListener(click, handler, false); // false 表示冒泡阶段监听默认6.2.2 阻止事件传播 方法作用event.stopPropagation()阻止事件继续冒泡或捕获event.stopImmediatePropagation()阻止同一元素上后续所有事件监听器执行event.preventDefault()阻止默认行为如表单提交、a 链接跳转 6.2.3 自定义事件CustomEvent 用于手动触发和传递自定义数据的事件。 1️⃣ 创建并触发事件 const event new CustomEvent(myEvent, {detail: { name: ChatGPT, level: 99 } }); element.dispatchEvent(event);2️⃣ 监听事件 element.addEventListener(myEvent, function(e) {console.log(e.detail.name); // 输出ChatGPT });6.2.4 事件对象 Event 当事件触发时监听函数会自动接收一个事件对象 属性/方法描述event.target实际触发事件的元素event.currentTarget当前绑定事件的元素event.type事件类型如 clickevent.timeStamp触发事件的时间戳event.defaultPrevented是否已调用 preventDefault()event.bubbles该事件是否支持冒泡event.cancelable是否可以取消默认操作 6.2.5 补充事件委托推荐实践 通过把事件绑定在父节点上提高性能和可维护性。 ul.addEventListener(click, function(e) {if (e.target.tagName LI) {console.log(点击了, e.target.innerText);} });✅ 好处 减少事件监听数量支持动态添加子元素的事件响应 6.2.6 事件绑定优先级顺序 在浏览器中当同一元素绑定了多种事件方式它们的触发顺序如下 ✅ 优先级顺序由高到低 内联绑定HTML 属性如 button onclickalert(1)DOM0 绑定传统方式如 element.onclick fnDOM2 绑定推荐方式如 element.addEventListener(click, fn) ⚠️ 示例说明 button idbtn onclickconsole.log(inline)点击/button const btn document.getElementById(btn); btn.onclick () console.log(DOM0); btn.addEventListener(click, () console.log(DOM2));输出顺序 inline DOM0 DOM26.2.7 DOM 0 / DOM 2 级事件模型差异 比较项DOM 0 级事件传统DOM 2 级事件标准绑定方式element.onclick fnaddEventListener(click, fn, useCapture)是否支持多个监听器❌ 只能绑定一个✅ 可绑定多个是否支持捕获阶段❌ 不支持✅ 支持通过第三个参数是否兼容 IE 低版本✅IE9是否标准推荐❌✅ W3C 推荐标准方式 6.2.8 React 合成事件机制SyntheticEvent React 并不直接绑定原生事件而是通过自己的事件系统合成事件实现更高效的管理。 特点 特性描述合成封装对原生事件进行封装统一不同浏览器差异自动绑定自动使用事件委托绑定在根节点提高性能统一池化使用事件池提升性能v17 前需注意事件异步访问命名风格使用驼峰命名如 onClick、onChange ✅ 示例 button onClick{handleClick}点击/buttonfunction handleClick(e) {console.log(e.nativeEvent); // 原生事件console.log(e); // 合成事件 }⚠️ 注意事项 异步中访问事件属性需要调用 e.persist()在 React17 以前React 17 不再使用事件池不再需要 e.persist() 6.3 BOM 操作 6.3.1 window 对象 浏览器的全局对象所有全局变量和函数都是其属性或方法。也是 BOM 的顶层对象。 常见属性/方法 属性/方法作用window.innerWidth / innerHeight获取窗口内容区域的宽/高不含滚动条window.open(url)打开新窗口或标签页window.alert() / confirm() / prompt()浏览器弹窗window.scrollTo(x, y)滚动到指定位置 6.3.2 location 对象 用于获取或修改当前页面的 URL。 属性/方法说明location.href当前完整 URL可读取或赋值跳转location.protocol协议如 https:location.host / hostname / port主机、主机名、端口号location.pathname路径部分location.search查询字符串如 ?id1location.reload()重新加载页面location.assign(url)跳转到新 URL有历史记录location.replace(url)替换当前页面无历史记录 6.3.3 navigator 对象 描述用户浏览器的信息。 属性说明navigator.userAgent浏览器/设备详细信息navigator.platform操作系统平台如 Win32navigator.language当前浏览器语言navigator.onLine当前是否联网布尔值 6.3.4 history 对象 用于操作浏览器历史记录。 方法说明history.back()返回上一页等同于点击后退history.forward()前进一页history.go(n)前进或后退 n 步history.pushState(state, title, url)添加历史记录不会刷新页面history.replaceState(...)替换当前历史记录 注意pushState 和 replaceState 是 HTML5 的新特性常用于 SPA 前端路由。 6.3.5 定时器setTimeout 与 setInterval 方法作用返回值setTimeout(fn, delay)延迟执行一次返回定时器 IDsetInterval(fn, delay)每隔一段时间重复执行返回定时器 IDclearTimeout(id)取消 setTimeoutclearInterval(id)取消 setInterval 示例 const id setTimeout(() console.log(一次性延迟), 1000); clearTimeout(id);const loopId setInterval(() console.log(每秒执行), 1000); clearInterval(loopId);⚠️ 注意内存泄漏风险组件销毁/页面离开应清理定时器。 好的以下是对 6.3 BOM 操作 的进一步补充涵盖浏览器窗口通信、全局错误处理以及实用 Web API 技巧帮助你建立更加系统的 JavaScript 浏览器编程知识体系。 6.3.6 浏览器窗口通信postMessage ✅ 场景 不同窗口/iframe 之间传递数据甚至跨域通常用于父页面与子页面之间的数据通信。 基本语法 // 发送方通常是父窗口或 iframe otherWindow.postMessage(message, targetOrigin);// 接收方 window.addEventListener(message, function(event) {// event.data 是传递过来的数据// event.origin 是消息来源的域名 }, false);✅ 参数说明 参数说明message发送的数据可以是对象targetOrigin接收方的 origin例如https://example.com用于安全校验-w41hk4oxqyc3z0h1aq79f/) 示例 // 子页面向父页面发送消息 window.parent.postMessage({ type: resize, height: 600 }, https://yourdomain.com);// 父页面接收子页面消息 window.addEventListener(message, (event) {if (event.origin ! https://yourdomain.com) return; // 安全校验console.log(子页面消息, event.data); });6.3.7 全局错误处理机制 ✅ window.onerror 用于捕获运行时错误防止页面崩溃时无反馈。 window.onerror function (message, source, lineno, colno, error) {console.error(捕获错误:, message, 位置:, source, lineno, colno);// 可上传日志服务器return true; // 阻止默认报错行为 };✅ window.addEventListener(error) 更强大可以捕获资源加载错误如图片、脚本加载失败 window.addEventListener(error, function (e) {if (e.target instanceof HTMLImageElement) {console.warn(图片加载失败, e.target.src);} }, true); // 第三个参数设为 true 才能捕获资源加载错误✅ window.addEventListener(unhandledrejection) 用于捕获未被 .catch() 捕获的 Promise 错误 window.addEventListener(unhandledrejection, (event) {console.error(未处理的 Promise 错误, event.reason); });6.3.8 Web API 实用技巧 ✅ 剪贴板 API // 复制文本到剪贴板 navigator.clipboard.writeText(复制的内容).then(() alert(已复制)).catch(err console.error(复制失败, err));// 读取剪贴板内容需 HTTPS 环境用户触发 navigator.clipboard.readText().then(text console.log(读取到剪贴板内容, text));⚠️ 注意安全性大多浏览器要求用户手势触发如点击 ✅ 页面可见性 APIPage Visibility 判断页面是否处于活跃当前标签页是否可见适合用于 暂停动画、视频播放控制数据轮询行为等。 document.addEventListener(visibilitychange, () {if (document.visibilityState hidden) {console.log(页面不可见暂停轮询);} else {console.log(页面可见恢复轮询);} });✅ 屏幕尺寸与滚动监听 // 获取滚动位置 window.scrollY; // 垂直滚动距离 window.scrollX; // 水平滚动距离// 监听页面滚动 window.addEventListener(scroll, () {console.log(滚动中..., window.scrollY); });七、模块化与工具链 7.1 模块化发展历程 模块化是前端工程化的核心。它的演化反映了前端开发复杂度的提升和工具生态的进化。 7.1.1 IIFE立即执行函数表达式 最原始的模块化方式用闭包封装变量避免污染全局作用域。 (function () {var name 模块内部变量;console.log(name); })();✅ 优点避免全局变量污染❌ 缺点无模块复用能力、缺乏依赖管理 7.1.2 CommonJSNode.js 中使用 // a.js module.exports {sayHi: () console.log(Hi), };// b.js const a require(./a.js); a.sayHi();✅ 特点同步加载适用于服务器端❌ 浏览器不支持需要打包工具如 Webpack转换 7.1.3 AMDAsynchronous Module Definition 浏览器端模块化规范代表库RequireJS define([moduleA], function (moduleA) {moduleA.doSomething(); });✅ 特点异步加载适合浏览器❌ 缺点语法繁琐、可读性差 7.1.4 UMDUniversal Module Definition 兼容 CommonJS、AMD 和浏览器全局变量 (function (root, factory) {if (typeof define function define.amd) {define([], factory);} else if (typeof exports object) {module.exports factory();} else {root.myModule factory();} })(this, function () {return {}; });7.1.5 ES6 模块化现代主流 // module.js export const name JS模块; export default function greet() {console.log(Hello ES Module); }// main.js import greet, { name } from ./module.js; greet();✅ 静态加载、编译时可分析依赖✅ 浏览器原生支持需 type“module”✅ 与打包工具完美结合 7.2 前端开发工具链概览 从代码撰写 → 转译兼容 → 打包构建 → 代码规范 → 性能优化全流程涉及以下关键工具 7.2.1 构建与打包工具 工具主要用途特点Webpack模块打包器配置灵活、插件强大、学习曲线略高Vite新一代构建工具极速启动、基于原生 ESM、现代开发优选Rollup打包库的首选工具构建体积小Tree-shaking 效果好 7.2.2 代码转译与语法支持 工具作用Babel将 ES6 代码转为向后兼容的 JavaScriptTypeScript增加类型系统、增强开发体验 7.2.3 代码质量与风格规范 工具用途ESLint静态代码检查防止潜在错误Prettier统一代码格式提升团队协作效率 ✅ 推荐配合 IDE 插件 Git Hooks 实现自动检查 修复 7.2.4 常见工具集成方式 项目初始化npm init vitelatest / create-react-app构建命令npm run build开发模式npm run dev通常开启热更新检查格式eslint src/、prettier --write . 补充建议 ✅ 强烈建议配合 husky lint-staged 实现提交前校验 npx husky-init npm install npx husky add .husky/pre-commit npx lint-staged八、ES6 新特性 ES6 是 ECMAScript 的重大升级版本后续 ES7 持续增强语法和内置能力使 JavaScript 更现代、更强大。以下按功能模块系统归纳。 8.1 语法增强与数据结构 8.1.1 解构赋值 快速提取对象或数组中的值 const { name, age } person; const [a, b] [1, 2];✅ 默认值、嵌套解构✅ 可用于函数参数 8.1.2 模板字符串 多行字符串 插值表达式 const msg Hello, ${user.name}!;8.1.3 扩展与收集运算符... 展开将数组/对象拆开 const arr2 [...arr1]; const obj2 { ...obj1 };收集函数剩余参数 function fn(...args) {}8.1.4 Symbol独一无二的值 创建唯一键适合定义私有属性 const sym Symbol(key); obj[sym] value;8.1.5 Set Map全新数据结构 特性SetMap存储值的集合键值对是否重复否否键唯一常用方法add, has, deleteset, get, has, delete const s new Set([1, 2, 2]); // 去重 const m new Map([[a, 1]]);8.1.6 可迭代对象与 for…of 可使用 for...of、...展开符 的对象Array、Map、Set、字符串等 for (const item of set) {}8.2 Class 与模块系统 8.2.1 class 类定义与继承 class Person {constructor(name) {this.name name;}greet() {console.log(Hi, ${this.name});} }✅ extends 实现继承✅ super() 调用父类构造器✅ 私有属性#privateName 8.2.2 模块系统import / export // 导出 export const name Tom; export default function greet() {}// 导入 import greet, { name } from ./module.js;支持默认导出 / 命名导出 / 重命名 / 整体导入 8.3 常用内置 API 与语法糖 8.3.1 新增 API 方法作用Object.entries(obj)返回键值对数组Object.values(obj)返回值数组Array.flat(depth)扁平化嵌套数组Array.includes(val)判断是否包含Promise.allSettled()所有 Promise 返回后统一处理无论成功失败 8.3.2 Nullish Coalescing?? 只有 null 或 undefined 才触发右侧默认值 const val input ?? 默认值;❌ 不会因 或 0 而触发 8.3.3 Optional Chaining?. 安全读取深层属性避免报错 const city user?.address?.city;记忆建议 ✅ 解构 展开多写函数参数和对象操作✅ Symbol对象私有成员✅ Set/Map处理去重与映射优于 Object✅ ?? 与 ?.null 安全写法高频出现于项目中 九、浏览器通信与网络 现代前端开发离不开浏览器与服务器之间的高效通信本章将系统梳理 AJAX、跨域机制、本地存储方案与 Web 通信能力。 9.1 浏览器请求方式 9.1.1 XMLHttpRequest 基础XHR 原始的 AJAX 技术核心支持事件监听与状态码处理 const xhr new XMLHttpRequest(); xhr.open(GET, /api/data); xhr.onreadystatechange function () {if (xhr.readyState 4 xhr.status 200) {console.log(xhr.responseText);} }; xhr.send();9.1.2 Fetch API 更现代的异步请求方式基于 Promise fetch(/api/data).then(res res.json()).then(data console.log(data)).catch(err console.error(err));✅ 更简洁✅ 默认不携带 cookie需配置✅ 不会自动 reject 4xx/5xx需手动判断 res.ok 9.1.3 封装 Fetch 常用方法 async function request(url, options {}) {const res await fetch(url, options);if (!res.ok) throw new Error(网络错误);return res.json(); }9.2 跨域处理策略 9.2.1 同源策略 协议 域名 端口号 三者相同才算同源 不同源会受到限制如 DOM 操作、AJAX 请求 9.2.2 解决方式对比 方法原理优缺点CORS设置响应头 Access-Control-Allow-Origin推荐标准方案JSONP利用 script 标签不受同源限制仅支持 GET请求安全性差代理转发本地服务器转发请求绕过浏览器限制需后端支持常见于开发环境PostMessage窗口间通信iframe 或新窗口跨域数据安全通信 9.3 本地存储方式对比 9.3.1 Cookie 每次请求自动携带常用于身份验证有大小限制~4KB支持设置过期时间、路径、域 document.cookie token123;path/;max-age3600;9.3.2 localStorage 永久存储直到手动清除单域名下最大约 5MB仅支持字符串 localStorage.setItem(key, value); localStorage.getItem(key);9.3.3 sessionStorage 页面会话级别标签页关闭即清除API 与 localStorage 相同 ✅ 对比总结 特性CookielocalStoragesessionStorage是否随请求发送✅❌❌生命周期可设置永久会话大小限制4KB5MB5MB跨标签页共享✅✅❌ 9.4 实用通信机制补充 9.4.1 浏览器窗口通信postMessage 用于主窗口与 iframe / 子窗口 / 弹窗间安全通信 window.postMessage(数据, https://other.com);window.addEventListener(message, (event) {console.log(event.origin, event.data); });9.4.2 全局错误监听 捕获 JS 报错信息便于上报与监控 window.onerror function (msg, url, line, col, error) {console.error(捕获错误:, msg, error); };window.addEventListener(error, (event) {console.log(资源加载错误:, event.target); });9.4.3 实用 Web API 技巧 API功能示例navigator.clipboard.writeText()写入剪贴板复制文本document.visibilityState页面可见性检测visibilitychange 监听navigator.onLine网络状态检测离线/在线判断Performance API页面性能分析performance.now() 好的下面是第九章浏览器通信与网络的进一步补充涵盖更深入的网络通信机制及相关 API包括 WebSocket、服务端事件SSE、网络状态检测、离线缓存等内容。 9.5 实时通信技术 9.5.1 WebSocket 长连接 一种在单个 TCP 连接上进行全双工通信的协议适合实时聊天、推送通知等场景。 使用示例 const socket new WebSocket(wss://example.com/socket);socket.onopen () {socket.send(Hello Server!); };socket.onmessage (event) {console.log(收到消息:, event.data); };socket.onerror (err) console.error(连接错误:, err); socket.onclose () console.log(连接关闭);✅ 持久连接适合高频交互❌ 需服务端配套支持维护成本高 9.5.2 Server-Sent EventsSSE 浏览器从服务端接收单向推送数据基于 HTTP const source new EventSource(/api/events);source.onmessage function (event) {console.log(服务端推送:, event.data); };✅ 简洁、自动重连、支持事件命名❌ 只支持单向、部分浏览器支持 9.6 网络状态与页面生命周期 9.6.1 网络状态检测 console.log(navigator.onLine); // true or falsewindow.addEventListener(online, () console.log(网络恢复)); window.addEventListener(offline, () console.log(网络断开));9.6.2 页面可见性检测 document.addEventListener(visibilitychange, () {if (document.visibilityState hidden) {console.log(页面隐藏);} else {console.log(页面可见);} });可用于暂停动画、视频、轮询请求 9.7 离线缓存与存储技术 9.7.1 Cache APIService Worker 配合 Service Worker 实现离线缓存、离线访问页面内容 caches.open(v1).then(cache {cache.addAll([/index.html, /styles.css]); });与 fetch 结合可拦截请求并返回缓存需 HTTPS 环境下注册 Service Worker 9.7.2 IndexedDB 浏览器提供的事务型数据库可存储结构化数据 const request indexedDB.open(myDB, 1); request.onsuccess (event) {const db event.target.result;console.log(数据库打开成功); };支持索引、事务、高容量数据常用于大型离线 Web 应用PWA 9.8 网络调优与安全 9.8.1 请求优化技巧 开启 Keep-Alive 复用连接使用 CDN 缓存静态资源图片懒加载 资源压缩合理使用缓存头部Cache-Control、ETag 9.8.2 网络安全机制 HTTPS 加密传输防 XSS/CSRF 攻击输入校验与输出转义设置 Content-Security-Policy 安全策略头 十、性能优化与安全 10.1 性能优化 10.1.1 资源懒加载 将不在视口内的资源延迟加载减少初始加载时间。 图片懒加载 img data-srcimage.jpg classlazyload altLazy Load ImageJavaScript 懒加载 const script document.createElement(script); script.src path/to/your/script.js; document.body.appendChild(script);适用场景 图片、视频、JavaScript 等 10.1.2 事件节流与防抖 节流 (Throttling) 和 防抖 (Debouncing) 用于控制频繁触发的事件如滚动、输入等。 防抖 function debounce(fn, delay) {let timer;return function (...args) {clearTimeout(timer);timer setTimeout(() fn(...args), delay);}; }节流 function throttle(fn, delay) {let last 0;return function (...args) {const now Date.now();if (now - last delay) {last now;fn(...args);}}; }10.1.3 DOM 优化 减少 DOM 操作 批量更新、避免频繁重排与重绘例如使用 DocumentFragment缓存查询结果 存储对 DOM 的查询结果避免重复查找 const button document.getElementById(myButton); // 使用变量缓存 DOM 查找10.1.4 异步加载与延迟加载 异步加载 使用 async 和 defer 属性来异步加载 JavaScript 文件避免阻塞渲染。 script srcscript.js async/script script srcscript.js defer/script分块加载 使用 Webpack 等工具进行代码分块按需加载提升初次加载速度。 10.1.5 缓存策略 缓存能够显著提高性能减少重复的网络请求。 Service Worker Cache API 在浏览器端缓存资源离线访问。HTTP 缓存 使用 Cache-Control 和 ETag 头部进行缓存控制。 // 在 Service Worker 中缓存请求资源 caches.open(v1).then((cache) {cache.add(/index.html); });LocalStorage / IndexedDB 在本地存储应用数据避免频繁请求数据。 10.1.6 图片与视频优化 图片格式优化 使用现代格式如 WebP来减少图片大小。SVG 图标替代位图图标SVG 比 PNG/JPG 更加灵活且文件更小。懒加载 只在用户滚动到页面时才加载图片。 10.2 前端安全 10.2.1 XSS跨站脚本攻击 攻击者通过注入恶意脚本窃取用户数据或篡改网页内容。 防御方法 输入验证与输出编码 对用户输入进行严格的验证和转义避免脚本执行。使用 CSP内容安全策略 来限制加载的脚本源。 meta http-equivContent-Security-Policy contentscript-src self避免内联脚本 使用外部脚本文件禁止内联 JavaScript 代码。 10.2.2 CSRF跨站请求伪造 攻击者伪造用户请求造成未授权操作。 防御方法 Token 验证 每次提交请求时附加一个唯一的 CSRF Token在表单或请求头中传递服务器验证是否匹配。SameSite Cookies: 使用 SameSite 属性限制 Cookie 在跨站请求时是否随请求一起发送。 document.cookie tokenyour_token; SameSiteStrict;;10.2.3 Clickjacking点击劫持 攻击者通过透明 iframe 诱使用户点击其并非意图点击的内容。 防御方法 使用 X-Frame-Options 头部阻止页面被嵌套在 iframe 中。 meta http-equivX-Frame-Options contentDENY10.2.4 内容安全策略CSP CSP 是一种防止 XSS 攻击的安全机制限制浏览器加载资源的源。 基本 CSP 配置 meta http-equivContent-Security-Policy contentdefault-src self; script-src self unsafe-inline;策略设计 default-src指定默认的加载源script-src限制脚本的来源style-src限制样式的来源 10.2.5 其他前端安全防护 HTTPOnly Cookie 防止 JavaScript 访问 Cookie增强安全性。HSTSHTTP 严格传输安全 强制浏览器与服务器之间使用 HTTPS 通信。 // 在服务器上启用 HSTS Strict-Transport-Security: max-age31536000; includeSubDomains两步验证 通过发送验证码或短信来加强用户的身份验证。 十一、项目实战与面试要点 11.1 项目实践 Todo List、画板、购物车、小型 SPA 实现调试技巧与错误捕获Try/Catch、window.onerror 11.2 面试高频题 手写 Promise、深拷贝、节流/防抖输出题、闭包题、原型继承题 十二、进阶方向推荐 TypeScript 基础与应用React / Vue / Svelte 框架精通前端架构、微前端、性能监控WebAssembly、Serverless、PWA
http://www.pierceye.com/news/36704/

相关文章:

  • 网站源码制作步骤深圳福田商城网站建设
  • 网站域名备案查询系统cms后台管理系统
  • 微信里面的小程序做神马网站优化排名
  • 东莞网站se外贸流程和专业知识点
  • 昆山做网站公司哪家好ui设计学什么
  • 建网站的步骤和方法界面设计器
  • 给客户做网站外贸展示网站多少钱
  • 做门窗网站怎么做全国企业信用公示信息公示网官网
  • 手机建网站软件wordpress无法进入文章
  • 网站域名与网站首页网址自己怎么在手机上设计装修
  • 怎么给QQ名片做网站哪些网站的做的好看的
  • 学做面包的网站wordpress totalpoll
  • 网站制作的页面比例大学生就业信息招聘网
  • 网站建设需要多少钱wordpress怎么获取数据
  • 网站可以改内链结构吗大连建设招标网
  • 网站建设行吗企业网网站怎么做
  • 网站ui设计欣赏设计师做兼职的网站
  • 软文发稿网站广州免费网站建设
  • 大理市建设局网站邢台同城
  • 宁夏建设厅网站6网页视觉设计是什么
  • 视频网站做app还是h5只用html5做网站
  • 网站建设模板简单html免费网页素材
  • 创建一个网站需要做哪些工作东莞 手机网站制作
  • 自己做图片的网站网站域名到期
  • 舆情网站百度网站搜索量提高
  • 监控设备公司企业网站源码单位做核酸检测的通知
  • 中卫网站建设哪家好网站开发好后版权归谁
  • 惠州住房和建设局网站西安企业门户网站建设
  • 上海网站建设联系青岛市城市建设投标网站
  • 三水网站设计国外可以做会员网站的网站