老生常谈-作用域 / 作用域链 / 闭包

老生常谈的问题了,来做个自我检测吧,看看自己是否还记得这些八股文。

作用域(scope)

  • 浅显的理解:作用域就是变量的可用范围(scope)。
  • 为什么要有作用域:目的就是防止不同范围的变量之间互相干扰。
js 复制代码
var x = 1;  // 全局作用域
function f(){ // 函数级作用域
    var y = 2
    function g() {
        var z = 3
    }
}

如上述例子:

  • 全局作用域:

    1. 不属于任何函数的外部范围称为全局作用域。
    2. 保存在全局作用域的变量称为全局变量。 优点:可反复使用。 缺点:全局污染--开发时禁止使用。
  • 函数作用域:

    1. 一个函数内的范围称为函数作用域,保存在函数作用域内的变量称为局部变量,注意并不是所有 {} 扩起来的就是函数作用域局部变量。如下:
js 复制代码
if(true){
    var b = '小王'
}
console.log(b) // 小王
// {} 外也可访问到 b 变量,记着之前面试被问到过和我说{}括起来的就是局部变量,大家可以抓住机会反驳。
// 对象的{}也不是作用域,里边的属性也不是局部变量。
// 除函数{}之外其余的{},都不是作用域。
  • 特例:形参变量也是函数内的局部变量。

  • 局部变量的特点:优点:不会被污染,缺点:无法反复使用。

作用域链(scopes/scope chain)

  • 在每个函数定义时,就已经规划好了自己专属的一个查找变量的路线图,称为作用域链。
  • 一个函数可用的所有作用域串联起来,就形成了当前函数的作用域链。
  • 当执行到某条语句时,JS引擎会自动延函数的作用域链查找要用的变量,查找路径如下:

如果最后找不到报错ReferenceError x is not defined

作用域本质

JS 中,作用域和作用域链都是对象结构。

  • 全局作用域:其实是一个名为window的对象所有全局变量和全局函数都是window对象成员。
  • 函数作用域:其实是js殷勤在调用函数时才临时创建的一个作用域对象。其中保存函数的局部变量,而函数调用完,函数作用域对象就释放了。

什么是闭包

  • 既重用变量又保护变量不被污染的一种编程方法。
  • 闭包就是每次调用外层函数时,临时创建的函数作用域对象。
  • 为什么外层函数作用域对象能留下来,因为被内层函数对象的作用域链引用,无法释放。
  • 只要希望给一个函数,保存一个即可反复使用,又不会被外界污染的专属局部变量时,就用闭包。

如何使用闭包

  1. 用外层函数包裹,要保护的变量和使用变量的内层函数。
  2. 在外层函数内部返回内层函数对象。
  3. 调用外层函数,用变量接住返回的内层函数对象。
js 复制代码
//第 1 步 : 用外层函数包裹要保护的变量和内层函数
function fn() {
    var total=1000
    // 第2步:返回内层函数对象
    return function pay(num) {
        total-=num
        console.log(total,num)
    }
}
// 第3步:调用外层函数,用变量接住内层函数对象。
var pay = fn()
// pay 接住的就是fn()返回出来的内层函数对象。

一句话概括闭包: 外层函数调用后,外层函数的作用域对象,被返回的内层函数的作用域链引用着,无法释放,就形成了闭包对象。

闭包缺点: 容易造成内存泄漏,所以及时释放不用的闭包,将保存内层函数对象的变量赋值为null,导致函数名变量与内层函数对象分开。

点赞收藏支持、手留余香、与有荣焉,动动你发财的小手哟,感谢各位大佬能留下您的足迹。

往期热门精彩推荐

浏览器相关热门推荐

🔥🔥🔥初探浏览器事件循环是如何工作的

🔥🔥🔥再探浏览器事件循环构建高性能 Web 应用程序

面试相关热门推荐

前端万字面经------基础篇

前端万字面积------进阶篇

实战开发相关推荐

前端常用的几种加密方法

探索Web Worker在Web开发中的应用

不懂 seo 优化?一篇文章帮你了解如何去做 seo 优化

【实战篇】微信小程序开发指南和优化实践

前端性能优化实战

聊聊让人头疼的正则表达式

获取文件blob流地址实现下载功能

Vue 虚拟 DOM 搞不懂?这篇文章帮你彻底搞定虚拟 DOM

移动端相关推荐

移动端横竖屏适配与刘海适配

移动端常见问题汇总

聊一聊移动端适配

Git 相关推荐

通俗易懂的 Git 入门

git 实现自动推送

更多精彩详见:个人主页

相关推荐
神明不懂浪漫4 小时前
【第七章】Java中的常用类
java·开发语言·前端·经验分享·笔记
GuWenyue9 小时前
放弃云端API!一套React+WebGPU本地LLM方案,零数据上传、离线可用
前端·人工智能·前端框架
原则猫10 小时前
函数/变量提升
前端
独泪了无痕11 小时前
Vue3 Hooks使用实战解析
前端·vue.js
shawxlee13 小时前
vue3在public下封装config.js自定义配置动态数据,可在打包后直接修改,方便后端部署及后续维护
前端·javascript·经验分享·vue·团队开发·js·项目优化
用户0595401744613 小时前
把记忆存储的回归测试从手工换成 Playwright + GitHub Actions,线上缺陷降低 80%
前端·css
触底反弹13 小时前
🚀 从 DOM0 级到 React 合成事件:前端事件监听的 20 年演进史
前端·react.js·面试
kyriewen13 小时前
我给前端项目的接口请求套了6层保护——才发现以前一直在裸奔
前端·javascript·面试
颜酱13 小时前
04 | 召回前置准备:搭好召回所需的四个数据库
前端·人工智能·后端
wdfk_prog13 小时前
嵌入式面试真题第 15 题:不可恢复异常后的通用崩溃快照、调用栈保存与离线分析架构
linux·开发语言·面试·架构