博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js下探究 let, var 之于闭包
阅读量:5835 次
发布时间:2019-06-18

本文共 1718 字,大约阅读时间需要 5 分钟。

js 是非常灵活的语言,写起来真是*

不过现在有了typescript,写起来舒服多了。

问题

在说js闭包,一定会牵涉到作用域。而一般在区别 var 跟 let 时就会举 for 循环的例子,但是这里只说 作用域,而不说闭包,那么其实还是看不懂,至于觉得很无厘头。

在阮一峰的 一节,举了这么一个例子。

var a = [];for (var i = 0; i < 10; i++) {  a[i] = function () {    console.log(i);  };}a[6](); // 10

var a = [];for (let i = 0; i < 10; i++) {  a[i] = function () {    console.log(i);  };}a[6](); // 6

然后我就不清楚了,为什么使用var全局变量后, 就输出10, 变成块级作用域let后就正常输出了。

动手

不知道到底怎么回事,只好调试去看变量到底是什么样?在两个例子中都稍微增加了点东西

var a = [];var b;var c;for (var i = 0; i < 10; i++) {    b = i;    c = i;    a[i] = function () {        console.log(i);        console.log(c);    };}

这里,循环里面有3个变量,内部函数中引用两个。然后我们循环次后,看看a[0], a[1]

clipboard.png

我们发现a[0], a[1]首先是个函数对象,在scopes 中有 Closure 这个东西,这就是闭包了。

这里闭包中只有 i跟c,并没有b, 因为b没有在内部函数中被使用,因此没有被scopes 记录下来。
而且请注意,i跟c的值都是当前变量i的值。 这也是闭包的属性的,能够记录下内部函数引用外部的值。因为 i, c, b 都是全局变量,所以循环也就是不断值覆盖,闭包并不会记录在循环时的值,只会记录 闭包变量。

注: 我这里是循环了3次,所以 闭包变量都是3,如果循环完了则是另外的值,你能正确说出它们的值么?

接着我们来看let 的改编

var a = [];let b;let c;for (let i = 0; i < 10; i++) {    b = i;    c = i;    a[i] = function oo() {        console.log(i);        console.log(c);    };}a[6](); // 6

同样,这里依旧i,b,c三个变量,内部函数中引用两个。然后我们循环次后,看看a[0], a[1]

clipboard.png

在上图,我们可以看到scopes 增加了个新东西 Block, 这是函数记录了 块作用域。

看着这个图,我们就可以这么理解: let声明的变量i 不是全局变量,每次循环都是作用域关闭然后重新再重建,但是在内部函数又引用了 这个块级作用域变量, 所以内部函数会记录这个值。

而变量c 虽然也是 let声明,为什么不是被记录到 Block 呢,这是因为 变量c 虽然是let声明,但是是在for循环外面, 对于这个文件来说,变量c就是全局变量,所以被记录到 closure

over

看完以上分析,不知道有没有加深你对let,const 的理解, let声明的变量是块级作用域,const声明的是全局变量,但也要看用在哪儿。 闭包时记录的 除了闭包变量还有块级作用域变量

最后来看看这个输出什么:

var a = [];let b;let c;for (let i = 0; i < 10; i++) {    b = i;    c = i;    var n = i;    let m = i;    a[i] = function oo() {        console.log(i);        console.log(c);        console.log(n);        console.log(m);    };}a[6]();

转载地址:http://iuycx.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
写Use Case的一种方式,从oracle的tutorial抄来的
查看>>
【C#】protected 变量类型
查看>>
Ubuntu解压
查看>>
爬虫_房多多(设置随机数反爬)
查看>>
藏地密码
查看>>
爬虫去重(只是讲了去重的策略,没有具体讲实现过程,反正就是云里雾里)...
查看>>
react中将px转化为rem或者vw
查看>>
8816
查看>>
avcodec_open2()分析
查看>>
何如获取单选框中某一个选中的值
查看>>
paip.输入法编程----删除双字词简拼
查看>>
tcp状态
查看>>
QQ悬浮返回顶部
查看>>
weblogic 9.2部署CXF Service应用
查看>>
MySQL建表语句的一些特殊字段
查看>>
DeDe调用指定栏目ID下的文章
查看>>
《Unix环境高级编程》读书笔记 第8章-进程控制
查看>>
腾讯前端二面题目详解
查看>>
mascara-1
查看>>