js闭包 偏执的太偏执、 2022-03-09 01:36 381阅读 0赞 **闭包指的是:能够访问另一个函数作用域的变量的函数**。 清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。 闭包就是将函数内部和函数外部连接起来的一座桥梁。 ![在这里插入图片描述][20190311224027593.png] 很多人会搞不懂匿名函数与闭包的关系,实际上,闭包是站在作用域的角度上来定义的,因为inner访问到outer作用域的变量,所以inner就是一个闭包函数。虽然定义很简单,但是有很多坑点,比如this指向、变量的作用域,稍微不注意可能就造成内存泄露。我们先把问题抛一边,思考一个问题:为什么闭包函数能够访问其他函数的作用域 ? 从堆栈的角度看待js函数 基本变量的值一般都是存在栈内存中,而对象类型的变量的值存储在堆内存中,栈内存存储对应空间地址。基本的数据类型: Number 、Boolean、Undefined、String、Null。 ![在这里插入图片描述][20190311224146642.png] 对应内存存储: ![在这里插入图片描述][20190311224227597.png] 当我们执行 b=\{m:30\}时,堆内存就有新的对象\{m:30\},栈内存的b指向新的空间地址( 指向\{m:30\} ),而堆内存中原来的\{m:20\}就会被程序引擎垃圾回收掉,节约内存空间。我们知道js函数也是对象,它也是在堆与栈内存中存储的,我们来看一下转化: ![在这里插入图片描述][20190311224652637.png] ![在这里插入图片描述][20190311224713704.png] 栈是一种先进后出的数据结构: 1 在执行fn前,此时我们在全局执行环境(浏览器就是window作用域),全局作用域里有个变量a; 2 进入fn,此时栈内存就会push一个fn的执行环境,这个环境里有变量b和函数对象fn1,这里可以访问自身执行环境和全局执行环境所定义的变量 3 进入fn1,此时栈内存就会push 一个fn1的执行环境,这里面没有定义其他变量,但是我们可以访问到fn和全局执行环境里面的变量,因为程序在访问变量时,是向底层栈一个个找,如果找到全局执行环境里都没有对应变量,则程序抛出underfined的错误。 4 随着fn1()执行完毕,fn1的执行环境被杯销毁,接着执行完fn(),fn的执行环境也会被销毁,只剩全局的执行环境下,现在没有b变量,和fn1函数对象了,只有a 和 fn(函数声明作用域是window下) 在函数内访问某个变量是根据函数作用域链来判断变量是否存在的,而函数作用域链是程序根据函数所在的执行环境栈来初始化的,所以上面的例子,我们在fn1里面打印变量b,根据fn1的作用域链的找到对应fn执行环境下的变量b。所以当程序在调用某个函数时,做了一下的工作:准备执行环境,初始函数作用域链和arguments参数对象 我们现在看回最初的例子outer与inner ![在这里插入图片描述][20190311224940783.png] 当程序执行完var inner = outer(),其实outer的执行环境并没有被销毁,因为他里面的变量a仍然被被inner的函数作用域链所引用,当程序执行完inner(), 这时候,inner和outer的执行环境才会被销毁调;《JavaScript高级编程》书中建议:由于闭包会携带包含它的函数的作用域,因为会比其他函数占用更多内容,过度使用闭包,会导致内存占用过多。 现在我们明白了闭包,已经对应的作用域与作用域链,回归主题: **坑点1: 引用的变量可能发生变化** ![在这里插入图片描述][20190311225432126.png] 看样子result每个闭包函数对打印对应数字,1,2,3,4,…,10, 实际不是,因为每个闭包函数访问变量i是outer执行环境下的变量i,随着循环的结束,i已经变成10了,所以执行每个闭包函数,结果打印10, 10, …, 10 怎么解决这个问题呢? ![在这里插入图片描述][20190311230044230.png] **坑点2: this指向问题** !\[!\[在这里插入图片描述\]([https://img-blog.csdnimg.cn/20190311230213757.png?)][https_img-blog.csdnimg.cn_20190311230213757.png] **坑点3:内存泄露问题** ![在这里插入图片描述][20190311231028309.png] **技巧1: 用闭包解决递归调用问题** ![在这里插入图片描述][20190311232037138.png] **技巧2:用闭包模仿块级作用域** es6没出来之前,用var定义变量存在变量提升问题 ![在这里插入图片描述][20190311232602160.png] 当然现在大多用es6的let 和const 定义。 [20190311224027593.png]: /images/20220309/6227fffee9e045f9ad0921face248df4.png [20190311224146642.png]: /images/20220309/403999c02e234316b40804f87eeb0ad3.png [20190311224227597.png]: /images/20220309/7d78f9a6c124498592346d381628f2d8.png? [20190311224652637.png]: /images/20220309/566f0bb9473e4ff58bee5042972c83e5.png [20190311224713704.png]: /images/20220309/3fcd4a1f94a64ca0a8b9e1f8ad1dbd1c.png? [20190311224940783.png]: /images/20220309/99c0fa2519364c97963dd208645711aa.png? [20190311225432126.png]: /images/20220309/fff5213dabc04d33805e923aeb80326d.png? [20190311230044230.png]: /images/20220309/2a68e3227d5b45d3b69c1cee59f72224.png? [https_img-blog.csdnimg.cn_20190311230213757.png]: https://img-blog.csdnimg.cn/20190311230213757.png?%29 [20190311231028309.png]: /images/20220309/ca38e9e596294caab175fd64a3fc14f7.png? [20190311232037138.png]: /images/20220309/9b2871b2a29145f6ae7223362c74a6d2.png? [20190311232602160.png]: /images/20220309/c383b1dc8a134da99c08c462e6745842.png?
相关 js闭包 所谓闭包,就是变量 从外部开始,到达父函数体,然后再从父函数体内的函数(子函数) 返回到父函数体,简单一句话概括:函数外部调用函数内部的变量。 通过下面的代码给出结果,解释一 朱雀/ 2022年08月13日 14:00/ 0 赞/ 255 阅读
相关 js闭包 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量的作用域 要理解闭包,首先必须理解Javascri Myth丶恋晨/ 2022年07月27日 16:38/ 0 赞/ 156 阅读
相关 JS——闭包 //在函数外部读取函数内部的变量 function c(){ var a=1000; function x(){ 以你之姓@/ 2022年06月04日 09:48/ 0 赞/ 277 阅读
相关 JS闭包 JS闭包 写在闭包之前: 上下文(context) 是一段程序运行所需要的最小数据集合。我们可以从上下文交换(context switch)来理解上下文,在多进程或多线 一时失言乱红尘/ 2022年05月25日 02:05/ 0 赞/ 310 阅读
相关 js闭包 闭包指的是:能够访问另一个函数作用域的变量的函数。 清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。 闭包就是将函数内部和函数外部连接起来的一座桥 偏执的太偏执、/ 2022年03月09日 01:36/ 0 赞/ 382 阅读
相关 js--闭包 前言 前一篇博客是介绍的作用域与作用域链,已经开始了JavaScript高级部分的学习,那么这篇博客简单的介绍一下js的闭包。 内容 所谓闭包就是函数 函数作 本是古典 何须时尚/ 2021年09月27日 04:24/ 0 赞/ 504 阅读
相关 js 闭包 闭包 > 闭包就是能够读取其他函数内部变量的函数。闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 ![6587 ╰半夏微凉°/ 2021年09月10日 07:52/ 0 赞/ 485 阅读
相关 JS闭包 JS闭包 一、什么是闭包 二、闭包的作用 三、闭包的案例 1.保留for循环中的var声明的i 2.循环里的定时器 一、什 分手后的思念是犯贱/ 2021年09月07日 06:10/ 0 赞/ 481 阅读
相关 js 闭包 <html> <head> <title>闭包</title> <meta charset="utf-8"> 梦里梦外;/ 2021年08月28日 01:13/ 0 赞/ 490 阅读
相关 js闭包 Js语言在函数内部可以直接读取全局变量,但函数外部无法读取函数内的局部变量 <script type="text/javascript"> var n=100 朱雀/ 2021年06月24日 16:00/ 0 赞/ 520 阅读
还没有评论,来说两句吧...