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

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

作用域(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 实现自动推送

更多精彩详见:个人主页

相关推荐
梨想橙汁14 小时前
Webpack 快速上手:前端工程化、打包原理、从零搭建基础项目
前端·webpack·前端工程化
zhanghaha131414 小时前
HTML系列教程:12_HTML 表格 <table> 零基础详解
前端·html
Betterme14 小时前
Vue3 竞态请求防护组合式hooks:useLatestRequest 设计思路
前端
_zhourui_h_14 小时前
一个 [ECS] 到底生成了多少代码?EasyECS 最核心的秘密都在这里
前端
梨想橙汁14 小时前
Git 分支详解:创建切换、合并分支、冲突解决实战
前端·git
雪芽蓝域zzs14 小时前
Vue3 defineProps` / `defineEmits` 是编译器宏,不需要手动 import 导入
前端·javascript·vue.js
whyweplay14 小时前
Elpis:从Json Schema 到 页面
前端·javascript
小白羊丨15 小时前
问数 Agent 整体架构、意图识别、历史上下文与 NL2SQL
java·面试·架构
大牧师15 小时前
Nest.js 微服务入门教程
开发语言·javascript·后端·微服务·node.js·nest.js·nest
做萤石二次开发的哈哈15 小时前
海康班班通交互一体机技能接入实战:ISAPI透传+OTAP双协议封装,Web/App/小程序教学管理应用一站生成
前端·物联网·小程序·交互·萤石开放平台·蓝海aiot一站式工作台·aiot开发