javascript 近乎神话般的概念:闭包

上面的例子你觉得输出的是什么呢?答案是Mike.在这里我们引出了一个新的概念,词法作用域作用域有两种模型:

词法作用域(静态):js查找是按照代码书写时候的位置来决定的,而不是按照调用时候位置

动态作用域:目前还有使用的有Perl,Bash (可以自行了解)

通过词法作用域的的规则我们可以再来分析一下

调用changeName()时,找到这个函数

定义var name = “Jay”

调用showName()

在changeName()里面查找是否有showName()这个方法,发现没有,向外层查找,找到了

调用console.log(name),在函数内部查找有没有name,没有,向外查找,找到了,name=“Mike”

输出Mike

闭包

了解了上面的知识之后,终于来到了闭包

闭包在两本书上的官方解释:

1.小"黄"书(你不知道的JavaScript): 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行.

2.红宝书(JavaScript高级程序设计): 闭包是指有权访问另一个 函数作用域中的变量的函数

非常抽象的一个概念,我自己的一个理解是:

当一个变量(就像上面的name)既不是该函数内部的局部变量,也不是该函数的参数,相对于作用域来说,就是一个自由变量(引用了外部变量),这样就会形成一个闭包.

怎么说呢?我们再来看看一开始我们使用的demo

let count = 500; //全局作用域

function foo1() {

let count = 0; //函数全局作用域

function foo2() {

let count2 = 1; //随便新增一个变量

// count++; 注释

debugger;

//console.log(count); 注释

//return count; 注释

}

return foo2; //返回函数

}

let result = foo1();

result(); //结果为1

result(); //结果为2

再次使用浏览器看看,这时我们就发现Closure已经消失了,这也就证实我说的,如果函数内部不调用外部的变量,就不会形成闭包.但是如果调用了外部变量,那么就会形成闭包. 这也就是说不是所有的函数嵌套函数都能形成闭包

最后我们再来看一个循环闭包的例子

for (var i = 1; i <= 5; i++) {

setTimeout(function timer() {

debugger;

console.log(i); // 输出什么?

}, 1000);

}

答案 6 6 6 6 6 .因为setTimeout里面的回调函数是一个异步的过程(异步代表可以不用等待我这个代码先执行完,可以先往后执行),而for循环是同步的(代码只能从上往下的执行),立即执行,异步的setTimeout必须等待一秒才能执行,这时i早已经循环结束了.

解决办法有三个:

将for循环中的var 改成let

for (let i = 1; i <= 5; i++) {

setTimeout(function timer() {

debugger;

console.log(i); // 1 2 3 4 5

}, 1000);

}

这样就没有问题了, 因为let是有块级的功能,每一层循环都是独立的,互不影响,所以才能正常输出.

  1. 把setTimeout()套上一个function

for (var i = 1; i <= 5; i++) {

log(i); // 1 2 3 4 5

}

function log(i) {

setTimeout(function timer() {

debugger;

console.log(i);

}, 1000);

}

这样同样能够实现这个功能,原理和第一个方法一样,每一个log()都是独立的,互不影响,这样才能有正确的结果,var就是因为没有块级的功能,才会出问题 3. 包装成匿名函数

for (var i = 1; i <= 5; i++) {

(function (i) {

setTimeout(function timer() {

debugger;

console.log(i);

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

总结一下

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

文件。

前端面试题汇总

  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值