Javascript作用域和闭包

作者: Xiao呆不糊涂 | 来源:发表于2018-01-22 15:48 被阅读49次

最近在重新学习JavaScript,在阅读你不知道的javascript时候,自己整理总结了些内容...所以想分享给大家。在分享的同时,也可以自己学习的更扎实...如果有错误或者理解不正确的地方,麻烦告知我会及时更正。同时也非常欢迎大家一起讨论。鞠躬。 Github地址:https://github.com/bsxz0604/RemarkForYouDontKnowJs (不定期更新...

作用域和闭包 Scope & Closures.png

1.词法作用域定义

词法作用域

分析过程:
作用域1 (绿色) :即全局作用域,包含变量foo;
作用域2 (黄色) :foo函数的作用域,包含变量a,bar,b
作用域3 (蓝色) :bar函数的作用域,包含变量c
bar 作用域里完整的包含了 foo 的作用域, 因为 bar 是定义在 foo 中的,产生嵌套作用域。值得注意的是,一个函数作用域只有可能存在于一个父级作用域中,不会同时存在两个父级作用域。还有诸如this , window , document等全局对象这里就不说了,避免混乱。

执行过程:
语句console.log寻找变量a,b,c;
其中c在自己的作用域中找到,
a,b在自己的作用域中找不到,于是向上级作用域中查找,在foo的作用域中找到,并且调用。
函数在执行时,每遇到一个变量,都会去执行期上下文的作用域链的顶部,也就是执行函数的激活对象开始搜索,如果在第一个作用域链(即,Activation Object 激活对象)中找到了,那么就返回这个变量。如果没有找到,那么继续向下查找,直到找到为止。如果在整个执行期上下文中都没有找到这个变量,在这种情况下,该变量被认为是未定义的。也就是说如果foo的作用域中也定义了c,但bar函数只调用自己作用域里的c。这就是我们说的变量取值。

2.闭包中经典for循环问题

for(var i = 0 ; i<3 ; i++ ){
  setTimeout( function (){
    console.info(i)
  },100)
}
//3 
//3
//3

在上面这段代码中,输出的是3个3, 而并非我们想的0 ~ 2
原因:for循环每次注册一个延迟函数, setTimeout是异步的,传入事件队列中,在循环结束后进行处理,当循环结束时,i为3。
setTimeout中的匿名function没有将 i 作为参数传入来固定这个变量的值, 让其保留下来, 而是直接引用了外部作用域中的 i, 因此 i 变化时, 也影响到了匿名function.
所以为了得到我们想要的0~2,这里我们可以利用闭包来完成

for( var i = 0 ; i<3 ; i++ ){ 
  setTimeout(
    (function time(j){ 
      return function(){console.info(j)}}
    )(i)
  ,100)
}
//0
//1
//2

当然,在ES6中,我们也可以直接使用let来完成
变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量.
JavaScript 引擎内部会记住上一轮循环的值,初始化每轮的变量i时,就在上一轮循环的基础上进行计算。

for(let i = 0 ; i<3 ; i++ ){
  setTimeout( function (){
    console.info(i)
  },100)
}
//0 
//1
//2

ps: for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

for(let i = 0 ; i<3 ; i++ ){
  setTimeout( function (){
    let i = 'abc';
    console.log(i);
  },100)
}
//abc 
//abc
//abc

相关文章

  • 2018-01-07 关于javascript闭包和作用域的理解

    关于 javascript 闭包的一些思考 作用域 词法作用域 函数作用域 块作用域 闭包 什么是作用域? 作用域...

  • 学习JavaScript闭包和作用域笔记

    JS JavaScript闭包和作用域 闭包 JavaScript高级程序设计中对闭包的定义:闭包是指有权访问另外...

  • 你不可不知道的 JavaScript 作用域和闭包

    原文出处:JavaScript Scope and Closures 作用域和闭包是 JavaScript 中重要...

  • 作用域和闭包

    目录 概述 作用域编译过程词法作用域全局作用域函数作用域 闭包循环和闭包闭包的用途性能 总结 概述 作用域和闭包一...

  • JavaScript中的闭包

    1.什么是闭包 要理解什么是闭包,就得先理解变量的作用域。在JavaScript中,有两种作用域,全局作用域和函数...

  • 作用域、作用域链、闭包、面向对象、执行上下文

    作用域 作用域链 函数的提前声明 闭包 JavaScript 闭包与类(原型链)之间的开发方式 构造函数和普通函数...

  • 2018-07-11

    深入理解闭包: 一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非...

  • 《javscript启示录》笔记(下)

    7. 作用域和闭包 a. 在javascript中作用域是执行代码的上下文,分为: 全局作用域 和 局部作用域(函...

  • JavaScript中的闭包

    理解闭包,首先必须理解变量作用域。前面提到,JavaScript 有两种作用域:全局作用域和函数作用域。函数内部可...

  • 作用域闭包

    概览 背景知识:JavaScript内存管理、JavaScript作用域。 内容 1 闭包定义 闭包:当函数可以记...

网友评论

    本文标题:Javascript作用域和闭包

    本文链接:https://www.haomeiwen.com/subject/gochnttx.html