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

javascript个人笔记 闭包/this/解构赋值/模板字符串/模块化

闭包

函数能够访问并记住其词法作用域(lexical scope)外的变量
用于封装私有变量,模块化

function outer() {let count = 0; // 外层函数的变量function inner() {count++; // 内层函数引用外层变量console.log(count);}return inner; // 返回内层函数
}const counter = outer();
counter(); // 输出 1
counter(); // 输出 2(count 被“记住”了)

outer的inner函数引用了外部的counter,outer函数执行完毕,count仍然会被保存
如果闭包中引用的大对象不再需要,需手动解除引用(如 null)(因为其有内存泄露风险

this

this 是一个 动态绑定 的上下文对象,它的值 取决于函数被调用的方式,而不是函数定义的位置(可以理解成每次调用函数,系统会自动帮助你传入一个this作为参数)

  1. 默认绑定(直接使用函数)
    this 指向:全局对象(浏览器中为 window,Node.js 中为 global)。严格模式(‘use strict’)下为 undefined
function showThis() {console.log(this);
}showThis(); 
// 非严格模式:window(浏览器)
// 严格模式:undefined
  1. 隐式绑定(作为对象方法调用)
const obj = {name: "Alice",sayHi() {console.log(`Hi, ${this.name}!`); // this就是obj本身}
};obj.sayHi(); // 输出 "Hi, Alice!"
  1. this 指向:call/apply/bind 的第一个参数。

区别:

call:立即调用,参数逐个传递。

apply:立即调用,参数以数组传递。

bind:返回一个新函数,不立即调用。

apply的理解
❌ 错误理解:apply 的第一个参数(this 指向)会被当作数组处理。

✅ 正确理解:

第一个参数:永远是 this 的指向(可以是任意类型,和数组无关)。

第二个参数:是一个数组(或类数组),数组中的元素会被“展开”作为函数的参数

function greet() {console.log(`Hello, ${this.name}!`);
}const user = { name: "Bob" };greet.call(user);    // 输出 "Hello, Bob!"
greet.apply(user);   // 同上
const boundFunc = greet.bind(user);
boundFunc();         // 输出 "Hello, Bob!"

4.new 绑定(构造函数调用)

this 指向:新创建的实例对象。

场景:使用 new 调用构造函数。

function Person(name) {this.name = name; // this 指向新实例
}const alice = new Person("Alice");
console.log(alice.name); // 输出 "Alice"
  1. 箭头函数(无自己的 this)
  2. this 指向:继承外层作用域的 this(词法作用域)
const obj = {name: "Alice",sayHi: function() {setTimeout(() => {console.log(`Hi, ${this.name}!`); // this 继承自 sayHi(指向 obj)}, 100);}
};obj.sayHi(); // 输出 "Hi, Alice!"

this指向陷阱

//闭包
const obj = {name: "Alice",outer() {function inner() {console.log(this.name); // 直接调用}inner(); // 直接调用}
};obj.outer(); // 输出 undefined//回调函数
const obj = {name: "Alice",fetchData(callback) {setTimeout(callback, 100); // 🚨 问题出在这里, 等价于直接调用函数},logName() {console.log(this.name);}
};obj.fetchData(obj.logName); // 输出 undefined// 伪代码:模拟 setTimeout 的行为
function setTimeout(callback, delay) {// 等待 delay 毫秒...callback(); // 🚨 这里直接调用,没有 obj 上下文!
}

解构赋值(Destructuring)

从数组或对象中提取值,并赋值给变量的一种简洁语法

const arr = [1, 2, 3];
const [a, b, c] = arr; // a=1, b=2, c=3const user = { name: "Bob", age: 30 };
const { name, age } = user; // name="Bob", age=30const { role = "guest" } = user; // 如果 user.role 不存在,role="guest"

模板字符串

反引号(`)包裹字符串,支持多行文本和嵌入表达式(${expression})

const name = "Alice";
// 单行字符串
const greeting = `Hello, ${name}!`; // "Hello, Alice!"// 表达式计算
const sum = `1 + 2 = ${1 + 2}`; // "1 + 2 = 3"

模块化

将代码分割成多个文件,通过 import/export 管理依赖关系。

//假定这个文件叫math.js
export const PI = 3.14;
export function sum(a, b) { return a + b; }// 默认导出(每个模块仅一个)
export default class User { /* ... */ }
// 导入命名导出
import { PI, sum } from './math.js';// 导入默认导出
import User from './User.js';// 动态导入(按需加载)
const module = await import('./module.js');
http://www.xdnf.cn/news/7590.html

相关文章:

  • JavaScript计时器详解:setTimeout与setInterval的使用与注意事项
  • DNS:互联网的“通讯录”——计算机网络应用层中的域名系统详解
  • Android Framework学习七:Handler、Looper、Message
  • 力扣-快乐数
  • 便捷的Office批量转PDF工具
  • MinIO的安装和使用
  • 设计模式之备忘录模式
  • 通过COM获取正在运行的Excel实例并关闭 c#实现
  • C++之set与map介绍
  • JavaScript 日志和调试工具箱-logger2js
  • 数据仓库是什么?常见问题解答
  • ELK简介和docker版安装
  • 硬件工程师笔记——三极管Multisim电路仿真实验汇总
  • 深入浅出:Spring Cloud Gateway 扩展点实践指南
  • Zookeeper 集群安装与脚本化管理详解
  • 【笔记】与PyCharm官方沟通解决开发环境问题
  • 测试W5500的第2步_使用ioLibrary库创建TCP客户端
  • 【razor】回环结构导致的控制信令错位:例如发送端收到 SR的问题
  • k8s 配置 Kafka SASL_SSL双重认证
  • 计算机网络基础概念
  • 新能源汽车焊接智能节气阀
  • uni-app 中使用 mumu模拟器 进行调试和运行详细教程
  • Matplotlib 高级进阶实战:多维度数据可视化组合图表
  • nbufxz动态规划1
  • 零基础设计模式——创建型模式 - 工厂方法模式
  • 【课堂笔记】核方法和Mercer定理
  • [Java实战]Spring Boot整合Sentinel:流量控制与熔断降级实战(二十九)
  • 数据集划分与格式转换:从原始数据到模型训练的关键步骤
  • 在 Excel 中使用通义灵码辅助开发 VBA 程序
  • 自学嵌入式 day21 - 数据结构 双向链表