JS 闭包难点剖析 ╰+攻爆jí腚メ 2022-10-27 06:24 131阅读 0赞 **目录** JavaScript 中的作用域是什么意思? 全局作用域 函数作用域 块级作用域 闭包会在哪些场景中使用? 闭包产生的原因 作用域链 通过定时器循环输出自增的数字通过 JS 的代码如何实现? 这是为什么呢 利用 IIFE 使用 ES6 中的 let 定时器传入第三个参数 -------------------- # JavaScript 中的作用域是什么意思? # JavaScript 的作用域通俗来讲,就是指变量能够被访问到的范围,在 JavaScript 中作用域也分为好几种,ES5 之前只有全局作用域和函数作用域两种。ES6 出现之后,又新增了块级作用域。 ## 全局作用域 ## 全局变量也是拥有全局的作用域,无论你在何处都可以使用它,在浏览器控制台输入 window.vName 的时候,就可以访问到 window 上所有全局变量。 ## 函数作用域 ## function getName () { var name = 'inner'; console.log(name); //inner } getName(); console.log(name); 上面代码中,**name** 这个变量是在 getName 函数中进行定义的,所以 name 是一个**局部的变量,**它的作用域就是在 getName 这个函数里边,也称作函数作用域。 除了这个函数内部,其他地方都是不能访问到它的。同时,当这个函数被执行完之后,这个局部变量也相应会被**销毁**。所以你会看到在 g**etName 函数外面的 name 是访问不到**的。从这点看,可以更好地理解**闭包**的含义: 闭包其实就是一个**可以访问其他函数内部变量**的**函数**。即一个定义在函数**内部**的函数,或者直接说闭包是个**内嵌函数**也可以。 ## 块级作用域 ## 其实就是在 JS 编码过程中 if 语句及 for 语句后面 \{...\} 这里面所包括的,就是块级作用域 ES6 中新增了块级作用域,最直接的表现就是新增的 let 关键词,使用 let 关键词定义的变量只能在块级作用域中被访问,有“暂时性死区”的特点,也就是说这个变量在定义之前是不能被使用的。 # 闭包会在哪些场景中使用? # > 红宝书闭包的定义:闭包是指有权访问另外一个函数作用域中的变量的函数。 > MDN:一个函数和对其周围状态的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。 闭包其实就是一个可以访问其他函数内部变量的**函数**。即一个定义在函数内部的函数,或者直接说闭包是个内嵌函数也可以。 ## 闭包产生的原因 ## ## 作用域链 ## 其实很简单,当访问一个变量时,代码解释器会首先在当前的作用域查找,如果没找到,就去父级作用域去查找,直到找到该变量或者不存在父级作用域中,这样的**链路**就是作用域链。 在创建compare()函数的时候,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的\[\[Scope\]\],如下图所示 当调用函数的时候,会为函数创建一个执行环境,然后复制函数的\[\[Scope\]\]属性中,此后还有活动对象 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTUxMTIzNg_size_16_color_FFFFFF_t_70][] function compare(value1,value2){ if (value1 >value2){ return -1 }else if(value1 < value2){ return 1 }else{ return 0 } } var res = compare(5,10) console.log(compare.prototype) ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTUxMTIzNg_size_16_color_FFFFFF_t_70 1][] # 通过定时器循环输出自增的数字通过 JS 的代码如何实现? # console.log("循环输出问题") for(var i = 1; i <= 5; i ++){ setTimeout(function() { console.log(i) }, 0) } ![20210203224452675.png][] ## 这是为什么呢 ## 1. setTimeout 为宏任务,由于 JS 中单线程 eventLoop 机制,在主线程同步任务执行完后才去执行宏任务,因此循环结束后 setTimeout 中的回调才依次执行。 2. 因为 setTimeout 函数也是一种闭包,往上找它的父级作用域链就是 window,变量 i 为 window 上的全局变量,开始执行 setTimeout 之前变量 i 已经就是 6 了,因此最后输出的连续就都是 6。 ## 利用 IIFE ## 可以利用 IIFE(立即执行函数),当每次 for 循环时,把此时的变量 i 传递到定时器中,然后执行,改造之后的代码如下。 for(var i = 1;i <= 5;i++){ (function(j){ setTimeout(function timer(){ console.log(j) }, 0) })(i) } ## 使用 ES6 中的 let ## ES6 中新增的 let 定义变量的方式,使得 ES6 之后 JS 发生革命性的变化,让 JS 有了块级作用域,代码的作用域**以块级为单位进行执行**。通过改造后的代码,可以实现上面想要的结果。 for(let i = 1; i <= 5; i++){ setTimeout(function() { console.log(i); },0) } ## 定时器传入第三个参数 ## setTimeout 作为经常使用的定时器,它是存在第三个参数的,日常工作中我们经常使用的一般是前两个,一个是回调函数,另外一个是时间,而第三个参数用得比较少。那么结合第三个参数,调整完之后的代码如下 for(var i=1;i<=5;i++){ setTimeout(function(j) { console.log(j) }, 0, i) } [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTUxMTIzNg_size_16_color_FFFFFF_t_70]: /images/20221024/cdc06b0507c1485baf05d9232df86453.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTUxMTIzNg_size_16_color_FFFFFF_t_70 1]: /images/20221024/89383e5150b647bbb8382d087465de00.png [20210203224452675.png]: /images/20221024/2f273c98953a4bd9bd0e070c4c66b8db.png
相关 JS 闭包难点剖析 目录 JavaScript 中的作用域是什么意思? 全局作用域 函数作用域 块级作用域 闭包会在哪些场景中使用? 闭包产生的原因 作用域链 通过定时器循环输出自 ╰+攻爆jí腚メ/ 2022年10月27日 06:24/ 0 赞/ 132 阅读
相关 js闭包 所谓闭包,就是变量 从外部开始,到达父函数体,然后再从父函数体内的函数(子函数) 返回到父函数体,简单一句话概括:函数外部调用函数内部的变量。 通过下面的代码给出结果,解释一 朱雀/ 2022年08月13日 14:00/ 0 赞/ 241 阅读
相关 js闭包 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量的作用域 要理解闭包,首先必须理解Javascri Myth丶恋晨/ 2022年07月27日 16:38/ 0 赞/ 142 阅读
相关 JS——闭包 //在函数外部读取函数内部的变量 function c(){ var a=1000; function x(){ 以你之姓@/ 2022年06月04日 09:48/ 0 赞/ 265 阅读
相关 JS闭包 JS闭包 写在闭包之前: 上下文(context) 是一段程序运行所需要的最小数据集合。我们可以从上下文交换(context switch)来理解上下文,在多进程或多线 一时失言乱红尘/ 2022年05月25日 02:05/ 0 赞/ 294 阅读
相关 js闭包 闭包指的是:能够访问另一个函数作用域的变量的函数。 清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。 闭包就是将函数内部和函数外部连接起来的一座桥 偏执的太偏执、/ 2022年03月09日 01:36/ 0 赞/ 368 阅读
相关 js--闭包 前言 前一篇博客是介绍的作用域与作用域链,已经开始了JavaScript高级部分的学习,那么这篇博客简单的介绍一下js的闭包。 内容 所谓闭包就是函数 函数作 本是古典 何须时尚/ 2021年09月27日 04:24/ 0 赞/ 488 阅读
相关 js 闭包 闭包 > 闭包就是能够读取其他函数内部变量的函数。闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 ![6587 ╰半夏微凉°/ 2021年09月10日 07:52/ 0 赞/ 468 阅读
相关 js 闭包 <html> <head> <title>闭包</title> <meta charset="utf-8"> 梦里梦外;/ 2021年08月28日 01:13/ 0 赞/ 474 阅读
相关 js闭包 Js语言在函数内部可以直接读取全局变量,但函数外部无法读取函数内的局部变量 <script type="text/javascript"> var n=100 朱雀/ 2021年06月24日 16:00/ 0 赞/ 498 阅读
还没有评论,来说两句吧...