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

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

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

更多精彩详见:个人主页

相关推荐
陈随易1 小时前
农村程序员-关于小孩教育的思考
前端·后端·程序员
云深时现月1 小时前
jenkins使用cli发行uni-app到h5
前端·uni-app·jenkins
昨天今天明天好多天1 小时前
【Node.js]
前端·node.js
亿牛云爬虫专家1 小时前
Puppeteer教程:使用CSS选择器点击和爬取动态数据
javascript·css·爬虫·爬虫代理·puppeteer·代理ip
2401_857610031 小时前
深入探索React合成事件(SyntheticEvent):跨浏览器的事件处理利器
前端·javascript·react.js
刘艳兵的学习博客1 小时前
刘艳兵-DBA033-如下那种应用场景符合Oracle ROWID存储规则?
服务器·数据库·oracle·面试·刘艳兵
雾散声声慢2 小时前
前端开发中怎么把链接转为二维码并展示?
前端
熊的猫2 小时前
DOM 规范 — MutationObserver 接口
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
天农学子2 小时前
Easyui ComboBox 数据加载完成之后过滤数据
前端·javascript·easyui
mez_Blog2 小时前
Vue之插槽(slot)
前端·javascript·vue.js·前端框架·插槽