news 2026/8/25 10:44:09

JavaScript作用域与闭包讲解 - JavaScript学习系列文章

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript作用域与闭包讲解 - JavaScript学习系列文章

一、什么是作用域?

简单来说,作用域就是变量起作用的范围.想象一下, 你在家里喊"开饭啦!",只有家里的人能听见; 在小区里喊, 整个小区都能听见; 在大街上喊...呃, 可能会被当成神经病. JavaScript的作用域也是类似的道理. 1) 全局作用域全局作用域就像是在大街上喊话, 所有人都能听见 (所有代码都能访问).

//全局变量, 在任何地方都能访问const globalMessage ="Hello World";
functionsayHello() {console.log(globalMessage);//可以访问全局变量}
sayHello();//输出"Hello World"console.log(globalMessage);//同样可以访问
但是要注意,滥用全局变量是个坏习惯!就像你不会在大街上喊你的银行卡密码一样, 太多全局变量容易造成命名冲突和难以维护. 2) 函数作用域函数作用域就像是在自己家里说话, 只有家里人能听见
functionfamilyMeeting() {const secret ="咱家存款有100万!";//函数作用域内的变量
console.log(secret);//可以访问}
familyMeeting();// console.log(secret); //报错!外面访问不到secret
3) 块级作用域块级作用域是ES6引入的, 用letconst声明的变量只在{}内有效.
if (true) {let blockScoped ="我在块里面";const alsoBlockScoped ="我也是";var notBlockScoped ="我不是块作用域";//var没有块级作用域}
console.log(notBlockScoped);//"我不是块作用域"// console.log(blockScoped); //报错// console.log(alsoBlockScoped); //报错

var没有块级作用域!它只有函数作用域. 这也是为什么现在推荐用letconst.

二、作用域链

现在来点进阶的——作用域链. 想象你在公司里:

1. 先在自己工位找文件(当前作用域)

2. 找不到就去部门公共区域找(外层作用域)

3. 还找不到就去公司档案室找(更外层作用域)

4. 最后可能去总部找(全局作用域)

JavaScript查找变量也是这样一层层往外找的:
const company ="阿里";//全局作用域
functiondepartment() {const team ="前端";//department函数作用域
functionmyDesk() {const name ="小明";//myDesk函数作用域console.log(name);//小明 (当前作用域)console.log(team);//前端 (上一层作用域)console.log(company);//阿里 (全局作用域)}
myDesk();}
department();
作用域链是在函数定义时就确定好的, 不是调用时确定的! 这就是所谓的"静态作用域". 三、闭包闭包是JavaScript中最强大的特性之一, 也是面试必问的.1) 闭包是指那些能够访问自由变量的函数(自由变量是指在函数中使用, 但既不是函数参数也不是函数局部变量的变量).当一个函数记住并访问它所在的词法作用域时, 就产生了闭包,即使这个函数是在当前词法作用域之外执行. 示例:
functionouter() {const secret ="我爱JavaScript";
functioninner() {console.log(secret);//访问外部函数的变量}
return inner;}
const myFunc =outer();myFunc();//"我爱JavaScript"
这里inner函数就是一个闭包, 因为它记住了outer的作用域, 即使outer已经执行完毕了. 2) 闭包的作用1-创建私有变量
functioncreateCounter() {let count =0;//这个变量外部无法直接访问
return {increment:function() {count++;console.log(count);},decrement:function() {count--;console.log(count);}};}
const counter =createCounter();counter.increment();//1counter.increment();//2counter.decrement();//1// console.log(count); // 报错, count不可访问
3) 闭包的作用2-函数柯里化柯里化是把接受多个参数的函数变成接受单一参数的函数的过程
functionmultiply(a) {returnfunction(b) {return a * b;};}
const double =multiply(2);console.log(double(5));// 10console.log(double(10));// 20
const triple =multiply(3);console.log(triple(5));// 15
4) 闭包的作用3-模块模式现代模块系统的基础就是闭包
const myModule = (function() {const privateVar ="我是私有的";
functionprivateMethod() {console.log(privateVar);}
return {publicMethod:function() {privateMethod();}};})();
myModule.publicMethod();//"我是私有的"// myModule.privateMethod(); //报错// console.log(myModule.privateVar); //undefined
5) 闭包使用的注意事项闭包虽好, 也有风险,内存泄漏风险:因为闭包会保留对外部变量的引用, 所以如果不小心, 可能会导致内存无法被回收.示例:
//不好的例子functionleakMemory() {const hugeArray =newArray(1000000).fill("0");
returnfunction() {console.log("我保留了hugeArray的引用");};}
const leakyFunc =leakMemory();//即使leakMemory执行完毕, hugeArray也不会被回收
6) 闭包与this
const obj = {name:"小明",sayName:function() {returnfunction() {console.log(this.name);};}};
obj.sayName()();//输出什么?
答案是undefined!因为内部函数的this指向全局对象(严格模式下是undefined),不是obj.解决方案: 保存this引用
const obj = {name:"小明",sayName:function() {const self =this;returnfunction() {console.log(self.name);};}};
obj.sayName()();//"小明"
或者使用箭头函数
const obj = {name:"小明",sayName:function() {return() => {console.log(this.name);};}};
obj.sayName()();// "小明"
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 10:42:53

深入解析AHB总线协议:SoC内部高速通信的核心机制与设计实践

1. 项目概述:AHB协议,SoC内部的高速公路如果你正在设计或验证一颗复杂的SoC芯片,或者你是一个嵌入式软件工程师,试图深入理解你写的代码是如何在芯片内部“跑”起来的,那么“AHB协议”这个概念你一定绕不开。它不是什么…

作者头像 李华
网站建设 2026/8/25 10:40:13

验证码技术演进:从字符识别到行为分析,开发者如何选择与集成

1. 从“图灵测试”到“人类测试”:验证码的进化与我的“智障”之旅不知道你有没有这样的经历:深夜想登录一个许久不用的网站,面对一个扭曲的、模糊的、让你怀疑自己是不是色盲的验证码,手指在屏幕上戳了半天,换来一句冷…

作者头像 李华
网站建设 2026/8/25 10:40:09

腾讯云轻量应用服务器WordPress一键部署:从快速建站到安全运维全指南

1. 项目概述:为什么“一键部署”在今天依然值得深挖?看到“10分钟WordPress建站”这个标题,很多老手可能会一笑置之,觉得这不过是又一个基础教程。但作为一个在网站运维和云服务领域摸爬滚打了十多年的从业者,我必须说…

作者头像 李华
网站建设 2026/8/25 10:35:55

OpenClaw Discord管理模块解析:权限校验、API调用与异常处理实践

1. 项目概述:从一行命令到社区治理的桥梁如果你正在探索如何为你的Discord服务器或社区平台构建一个智能、自动化的管理助手,那么OpenClaw这个名字你肯定不会陌生。作为一个开源的、可扩展的AI Agent框架,OpenClaw的核心魅力在于它能够将大语…

作者头像 李华
网站建设 2026/8/25 10:35:02

一台电脑怎么跑出四人分屏?Nucleus Co-Op 本地多人配置指南

一台电脑怎么跑出四人分屏?Nucleus Co-Op 本地多人配置指南 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 你是不是也遇到过这种场面&…

作者头像 李华