JS知识小笔记

发布时间:2026/5/20 8:02:24

JS知识小笔记 目录一、作用域可拓展二、闭包1.闭包Closure2.闭包的使用场景3.闭包的实际应用(可拓展)4.闭包的缺陷三.this四.面向过程和面向对象5. 模块化 (import / export)6. Promise7. async / await8. Class (类)总结实践建议提示以下是本篇文章正文内容下面案例可供参考一、作用域可拓展作用域决定了变量、函数和对象在代码中的可访问性。JavaScript中的作用域分为以下几种全局作用域函数作用域块级作用域词法作用域模块作用域动态作用域作用域链二、闭包1.闭包Closure是指一个函数能够访问并记住其词法作用域Lexical Scope即使这个函数在其词法作用域之外执行。闭包是 JavaScript 中非常强大的特性它允许函数“记住”并访问定义时的环境即使这个环境已经不再存在。const foo (){ var arr[]; var i; for (i0;i10;i){ arr[i]function In(){ console.log(i); } } return arr[0]; }在这个代码中由于内部函数In调用外部变量i 即使foo函数执行完毕var i 仍会被In记住,此时In就形成了一个闭包2.闭包的使用场景-当使用FP的时候基本就会使用闭包-当一个函数执行和上下文相关就有闭包-闭包是用来保存执行环境的也包括环境内的变量3.闭包的实际应用(可拓展)3.1.1 数据封装3.1.2 回调函数3.1.3 函数柯里化3.1.4 模块模式4.闭包的缺陷影响性能:过度使用闭包尤其是循环创建会降低性能内存泄漏:闭包会导致其词法作用域中的变量无法被垃圾回收从而可能导致内存泄漏三.this非严格模式this普通函数被调用时因为全局的方法和属性都是window对象的方法和属性所以this指向全局对象浏览器中的window严格模式下this的值是undefined。函数调用对象this当函数作为对象的方法调用时this指向该对象。当函数作为构造函数调用时this指向新创建的对象。函数通过new关键字调用this指向新创建的实例对象箭头函数中的this首先箭头函数没有自己的this全局作用域下箭头函数的this指向全局对象而在对象的方法中使用箭头函数时this指向定义箭头函数时所在上下文的this值。注意箭头函数没有自己的arguments对象。不能用作构造函数不能用new调用。没有prototype属性。事件处理函数中的this在DOM事件处理函数中this默认指向触发事件的DOM元素。显式绑定thiscallapplybind可以显式的绑定this指向特定对象。四.面向过程和面向对象1.JS对象的创建//JS对象的创建 Object.create(); var bar {}; new 关键字; //三者的区别Object.create()创建了一个对象 let p Object.create(q) ; // -p._proto_q;旧的var声明有作用域混乱、变量提升等问题。p的原型指向q//原型链当需要调用p对象的一个方法或属性时如果p上没有则去q5. 模块化 (import / export)为什么需要将代码拆分成独立的模块便于管理、复用和维护避免全局污染。导出export// module.js // 1. 命名导出可以有多个 export const apiKey 123abc; export function sum(a, b) { return a b; } export class Person {} // 或统一导出 const apiKey 123abc; function sum(a, b) { return a b; } export { apiKey, sum }; // 推荐此方式 // 2. 默认导出只能有一个 export default function() { console.log(默认导出); } // 或 const myFunc () {}; export default myFunc;导入import// app.js // 1. 导入命名导出必须用花括号名字要匹配 import { apiKey, sum } from ./module.js; // 重命名 import { apiKey as key, sum as add } from ./module.js; // 全部导入为一个对象 import * as module from ./module.js; console.log(module.apiKey); // 2. 导入默认导出不用花括号名字任意 import myFunction from ./module.js; // 3. 混合导入 import myFunction, { apiKey, sum } from ./module.js;6. Promise为什么需要解决传统回调函数的“回调地狱”问题用更优雅的方式处理异步操作。三种状态pending进行中、fulfilled已成功、rejected已失败。基本用法const myPromise new Promise((resolve, reject) { // 执行异步操作比如网络请求 setTimeout(() { const success true; if (success) { resolve(操作成功); // 状态从 pending - fulfilled } else { reject(操作失败); // 状态从 pending - rejected } }, 1000); }); // 使用 .then() 处理成功.catch() 处理失败 myPromise .then(result { console.log(result); // 操作成功 }) .catch(error { console.error(error); // 操作失败 }) .finally(() { console.log(无论如何都会执行); // 清理工作 });doSomething().then(result doSomethingElse(result)).then(newResult doThirdThing(newResult)).then(finalResult console.log(最终结果: ${finalResult})).catch(error console.error(错误: ${error}));// 清晰、线性避免了层层嵌套的回调Promise.all([promise1, promise2, promise3]) // 全部成功才成功一个失败就失败 .then(values { /* values 是结果的数组 */ }); Promise.race([promise1, promise2]) // 哪个先完成就用哪个的结果 .then(value { /* 第一个完成的结果 */ }); Promise.allSettled([promise1, promise2]) // 等全部完成无论成功失败 .then(results { /* 包含状态和结果的数组 */ });7. async / await为什么需要让异步代码的写法像同步代码一样直观是基于 Promise 的语法糖。基本规则async函数总是返回一个 Promise。await只能在async函数内部使用它会暂停函数的执行等待 Promise 完成并返回结果。用法// 用 async/await 重写上面的 Promise 链 async function doTasks() { try { const result await doSomething(); // 等待 doSomething() 完成 const newResult await doSomethingElse(result); // 用上一个结果继续 const finalResult await doThirdThing(newResult); console.log(最终结果: ${finalResult}); } catch (error) { console.error(错误: ${error}); } finally { console.log(清理工作); } } doTasks(); // 调用 async 函数返回的也是 Promise优点代码完全是线性的没有回调可读性极强。并行处理async function fetchData() { // 顺序执行一个接一个 const user await fetchUser(); const posts await fetchPosts(); // 并行执行同时开始 const [user, posts] await Promise.all([fetchUser(), fetchPosts()]); }8. Class (类)为什么需要为 JavaScript 提供更接近传统面向对象语言的、清晰的语法来创建对象和处理继承。基本语法class Person { // 构造函数 constructor(name, age) { this.name name; this.age age; } // 实例方法添加到原型上 greet() { return 你好我是${this.name}; } // 静态方法属于类本身实例不能调用 static info() { return 这是一个Person类; } } const p1 new Person(元, 1); console.log(p1.greet()); // 你好我是元 console.log(Person.info()); // 这是一个Person类继承class Student extends Person { constructor(name, age, grade) { super(name, age); // 必须先调用父类的 constructor this.grade grade; } // 重写父类方法 greet() { return super.greet() 是一名${this.grade}年级学生。; } } const s1 new Student(小明, 18, 高三); console.log(s1.greet()); // 你好我是小明是一名高三年级学生。Getter / Setterclass Rectangle { constructor(width, height) { this._width width; this._height height; } get area() { // 像属性一样访问 return this._width * this._height; } set width(value) { // 像属性一样设置 if (value 0) this._width value; } } const rect new Rectangle(10, 5); console.log(rect.area); // 50 (不是 rect.area()) rect.width 20; // 触发 setter重要提示JavaScript 的 class 本质仍是基于原型的继承的语法糖理解原型链仍然至关重要。总结变量提升函数提升Js本身没有类Js万物皆对象this 是动态绑定的取决于函数调用的上下文。普通函数调用时this 指向全局对象非严格模式或 undefined严格模式。对象方法调用时this 指向该对象。构造函数调用时this 指向新创建的实例。箭头函数没有自己的 this它会继承外部函数的 this。显式绑定通过 call()、apply() 或 bind() 可以显式设置 this。理解 this 的关键在于调用时的环境它决定了 this 的指向。实践建议立即实践在你的代码中全面替换掉 var改用 let/const。拥抱简洁在合适的场景特别是需要固定 this时使用箭头函数。告别拼接所有字符串拼接都用模板字符串。善用解构在函数参数、数组/对象取值时优先考虑解构。模块化思维任何项目都应拆分为模块用 import/export管理。异步首选处理异步操作时优先使用 async/await其次是 Promise尽量避免传统回调。组织代码当需要创建多个相似对象或有继承关系时使用 class来组织代码。这些特性共同构成了现代 JavaScript 开发的“标准语法”掌握它们是写出高质量、可维护代码的前提

相关新闻