-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【进阶2-3期】JavaScript深入之闭包面试题解 #19
Comments
第一个会消失 外界不存在对这个闭包的引用了 就被垃圾回收了 |
两个都是local scope,查找变量和定义函数时的作用域链有关,和执行上下文无关。 |
你不知道的javascript中说只要在函数定义域外调用函数,函数就会持有原定义域的闭包 |
都是"local scope",但是一个执行完毕就没有变量引用f,则会释放f相关的变量等。 |
作用域链其实就是等同于创建词法环境吧,只是说法不一样 |
for 循环中定义的 i 视为块级作用域中定义的变量并不正确,因为 for 循环的执行体内仍然可以定义 let i |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
本期的主题是作用域闭包,本计划一共28期,每期重点攻克一个面试重难点,如果你还不了解本进阶计划,文末点击查看全部文章。
如果觉得本系列不错,欢迎点赞、评论、转发,您的支持就是我坚持的最大动力。
作用域指的是一个变量和函数的作用范围,JS中函数内声明的所有变量在函数体内始终是可见的,在ES6前有全局作用域和局部作用域,但是没有块级作用域(catch只在其内部生效),局部变量的优先级高于全局变量。
作用域
变量提升
上面的代码输出是
undefined
,这是因为局部变量scope
变量提升了,等效于下面注意,如果在局部作用域中忘记var,那么变量就被声明为全局变量。
没有块级作用域
上篇文章已经介绍过了,【进阶2-2期】JavaScript深入之从作用域链理解闭包
作用域链
每个函数都有自己的执行上下文环境,当代码在这个环境中执行时,会创建变量对象的作用域链,作用域链是一个对象列表或对象链,它保证了变量对象的有序访问。
作用域链的开始是当前代码执行环境的变量对象,常被称之为“活跃对象”(AO),变量的查找会从第一个链的对象开始,如果对象中包含变量属性,那么就停止查找,如果没有就会继续向上级作用域链查找,直到找到全局对象中
闭包
上面在函数中返回了两个闭包,这两个闭包都维持着对外部作用域的引用。闭包中会将外部函数的自由对象添加到自己的作用域链中,所以可以通过内部函数访问外部函数的属性,这也是javascript模拟私有变量的一种方式。
闭包面试题解
由于作用域链机制的影响,闭包只能取得内部函数的最后一个值,这引起的一个副作用就是如果内部函数在一个循环中,那么变量的值始终为最后一个值。
这个代码已经贴过了,怕你们忘记,就再贴一遍
如果要强制返回预期的结果,怎么办???
方法1:立即执行函数
方法2:返回一个匿名函数赋值
无论是立即执行函数还是返回一个匿名函数赋值,原理上都是因为变量的按值传递,所以会将变量
i
的值复制给实参num
,在匿名函数的内部又创建了一个用于访问num
的匿名函数,这样每个函数都有了一个num
的副本,互不影响了。方法3:使用ES6中的let
解释下原理:
循环时,
let
声明i
,所以整个块是块级作用域,那么data[0]这个函数就成了一个闭包。这里用{}表达并不符合语法,只是希望通过它来说明let存在时,这个for循环块是块级作用域,而不是全局作用域。上面的块级作用域,就像函数作用域一样,函数执行完毕,其中的变量会被销毁,但是因为这个代码块中存在一个闭包,闭包的作用域链中引用着块级作用域,所以在闭包被调用之前,这个块级作用域内部的变量不会被销毁。
当执行
data[1]()
时,进入下面的执行环境。在上面这个执行环境中,它会首先寻找该执行环境中是否存在
i
,没有找到,就沿着作用域链继续向上到了其所在的块作用域执行环境,找到了i = 1
,于是输出了1
。思考题
代码1:
代码2:
上面的两个代码中,
checkscope()
执行完成后,闭包f
所引用的自由变量scope
会被垃圾回收吗?为什么?参考
进阶系列目录
交流
进阶系列文章汇总:https://github.com/yygmind/blog,内有优质前端资料,欢迎领取,觉得不错点个star。
我是木易杨,网易高级前端工程师,跟着我每周重点攻克一个前端面试重难点。接下来让我带你走进高级前端的世界,在进阶的路上,共勉!
The text was updated successfully, but these errors were encountered: