js忍者秘籍读书笔记(前五章)闭包

2 篇文章 0 订阅
1 篇文章 0 订阅
本文深入探讨JavaScript中的闭包概念,解释其如何实现私有变量,并通过实例展示闭包在减少代码复杂性和实现高级功能中的作用。闭包允许函数访问外部变量,即使在其定义的作用域之外。它创建了一个作用域链,存储闭包信息,直到不再需要时才进行垃圾回收。闭包在动画、事件绑定等场景中避免了全局变量冲突,提高了代码的组织和效率。同时,了解执行上下文和调用栈对于理解闭包工作原理至关重要。
摘要由CSDN通过智能技术生成

这一章的目标是:理解闭包、掌握闭包的工作原理

闭包的好处:

  1. 可以实现JavaScript没有的私有变量
  2. 可以通过减少代码数量和复杂度来添加高级特性

什么是闭包呢?(自己的理解)
内部函数调用外部函数的变量可以形成闭包

理解闭包

 允许函数访问并操作函数外部的变量
var globe_name = ''
function fn() {
     var name = 'tom'
     function fn_name() {
         return name
     }
     globe_name = fn_name()
 }
 fn()
 console.log(globe_name);// tom

以上代码就是一个闭包

按理说,fn方法执行完之后,这个作用域应该消失,不会再获取到内部的变量,但是现在执行内部函数时候内部变量仍然存在

当在外部函数中申明内部函数时,不仅仅定义 函数的声明,而且还创建了一个闭包。改闭包不仅包含了函数的声明,还包含了函数声明时该作用域中所有的变量。当最终执行内部函数是,尽管声明时的作用域已经消失了,但是通过闭包,仍然能访问到原始作用域

谨记
每一个通过闭包访问变量的函数都具有一个作用域链,作用域链包含闭包的全部信息

虽然表报是非常有用的,但是不能过度使用。使用闭包时,所有的信息都会存储在内存中,知道JavaScript引擎确保这些信息不再使用(可以安全的进行垃圾回收)或页面卸载时,才会清理这些信息

闭包的使用

JavaScript没有私有变量,但是闭包可以实现一个类似于其他语言的私有变量

function Obj(num1) {
   let num = num1 // 闭包模拟私有变量
   this.getNum = function () {
       return num
   }
   this.addNum = function () {
       num++
   }
}

let a = new Obj(2)
a.addNum()

上面的例子,其中可以通过getNum方法可以获取私有变量num的值,但是不能直接访问num这个私有变量。并且不能修改,有效的阻止了对变量不可控的修改
在外部是不能直接访问num的

回调函数中使用闭包

下面代码实现一个动画

let box1 = document.getElementById('box1')
let box2 = document.getElementById('box2')
function animation(ele) {
    let ticket = 0
    let timer = 0
    timer = setInterval(function () {
        if (ticket < 100) {
            ticket++
            ele.style.width = `${ticket}px`
        } else {
            clearInterval(timer)
        }
    }, 100)

}
animation(box1)
animation(box2)

假设,这个动画没有使用闭包来完成,则里面使用的变量ele(DOM元素的引用)、ticket(计数器)、timer(计时器)都得是全局变量,这样一个元素使用动画的时候没有问题,但是如果是多个的话,就会出问题,变量会发生冲突。
所以使用闭包,就会使得每个动画都能够有自己的作用域链中的私有变量,不会互相影响

使用闭包的理由
一次性同时做许多事情,例如事件绑定、动画甚至是服务端请求都会变得非常困难

这里这个动画例子让我想起来在刚学习js的时候写了一个轮播图,当时是写了一个全局的方法,也需要使用计数器和定时器,但是页面会有多个地方需要使用轮播图,所以写了公共的方法。然后在执行的时候发现页面轮播图效果没有按照预期效果执行,计数器的累加错误导致不同地方的轮播图没有按照顺序显示,后来就改成了构造函数来实现,这样计数器就没有再被互相影响,当时只知道这么写管用,但是不知道原因,现在理解了。

当时出现问题的原因就是因为执行元素没有属于自己的私有变量,导致被互相影响

通过执行上下文来跟踪代码

前面讲过JavaScript有两种代码类型:一种是全局函数、一种是函数代码

既然有两种类型的代码,name就有两种执行上下文:全局执行上下文和函数执行上下文

二者差别是:
全局执行上下文只有一个,当JavaScript程序开始执行时就有奖创建了全局上下文;而函数执行上下文是在每次调用函数时,就会创建一个新的

执行上下文也称为调用栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值