为何两段JavaScript代码未报错?闭包与作用域疑问求解
为什么这两段JavaScript代码不会报错?
这两个例子能正常运行,核心原因是JavaScript的闭包机制——函数会记住自己创建时所在的词法作用域,哪怕函数在其他作用域执行,依然能访问原作用域里的变量。
示例1解释
on = (callback) => { callback() } function test (){ let x = 'hello' on(() => { console.log(x); }) } test()
on函数只是负责接收并调用传入的回调,它自己的作用域里根本不需要用到x。真正访问x的是传给on的那个箭头函数,这个箭头函数是在test函数内部创建的,test里的x属于它的“原生环境”变量。- 当
test执行时,先声明了x='hello',接着调用on并传入箭头函数。on同步调用这个回调时,箭头函数会回到自己创建时的test作用域找x——此时test还没执行完(on是同步执行的),x还在当前执行上下文中,所以能正常打印,不会报错。
示例2解释
on = (callback) => { callback() } function test (){ let x = 'hello' on(() => { setTimeout(() => {console.log(x)}, 1000); }) } test()
- 这里多了一层
setTimeout,但本质还是闭包在起作用:setTimeout的内层箭头函数依然“绑定”了test里的x。 - 你可能以为
test执行完后,x会被销毁?但只要有函数还引用着x所在的作用域,JavaScript的垃圾回收机制就不会回收这个作用域。1秒后setTimeout的回调执行时,依然能通过闭包访问到test作用域里的x,所以依然能正常打印,不会报错。
内容的提问来源于stack exchange,提问作者abel-mak
相关产品推荐
相关产品推荐

