美文网首页
JS let/for循环问题/作用域/上下文环境随笔

JS let/for循环问题/作用域/上下文环境随笔

作者: 377b79b94683 | 来源:发表于2017-07-17 21:25 被阅读280次
遇到这么个题,结果因吹丝挺 试了一下这样结果更因吹丝挺了 ???什么鬼???

setTimeout会把回调放到代码执行完毕后,再做处理,so


显然setTimeout里的1是在程序执行完毕后才执行的

所以就不难理解为什么第一张图会打印5个5了,因为不管setTimeout再快,也得在程序执行完毕后打印,而程序执行完毕时,for已经循环了5次了.....

所以呢,还有个问题,在setTimeout把方法放到任务队列之后,会不会保留上下文环境?答案是肯定的。

  • 无论函数是在哪里调用,也无论函数是如何调用的,其确定的词法作用域永远都是在函数被声明的时候确定下来的。
  • 当定义一个函数时,它实际上保存一个作用域链。
  • 当调用这个函数时,它创建一个新的对象来储存它的参数或局部变量,并将这个对象添加保存至那个作用域链上,同时创建一个新的更长的表示函数调用作用域的“链”。
  • 对于嵌套函数来说,情况又有所变化:每次调用外部函数的时候,内部函数又会重新定义一遍。因为每次调用外部函数的时候,作用域链都是不同的。内部函数在每次定义的时候都要微妙的差别---在每次调用外部函数时,内部函数的代码都是相同的,而且关联这段代码的作用域链也不相同。
好烦啊终于搞定了,这样就可以证明在使用let的情况下每次循环中声明的回调的作用域链被固定下来啦
  • 当使用var声明变量的时候,没有块级作用域,因此每次循环中声明的setTimeout的回调,是去更高一级的作用域中寻找变量i。
  • 当使用let声明变量的时候,有独立的块级作用域,因此声明setTimeout回调的时候,是在本次循环的块级作用域{}中寻找变量i。

如上图,在定义循环时,同时定义n,在回调中修改n的值以修改回调执行结果,如果是var声明的,则第一次执行的结果会对后面两次造成影响,而使用let声明n,则三次循环完全互不干扰,可知在使用let定义n时,循环定义的三个回调函数的作用域链被各自分隔开。var声明的i和let声明的i在作用域链上的位置不同。

最后总结一下:

不管是var也好,let也好,循环定义的若干个setTimeout的回调都属于同一个上级作用域,但是回调之间是独立存在的,不会相互影响;不一样的是:var和let在各自作用域链上的位置不同,var没有块级作用域,所以var所在作用域属于上级作用域;let有块级作用域,所以在for循环的时候,i的作用域被限制在了{}代码块之间,分别在三个{}中定义setTimeout回调的时候,i在作用域链中的位置分属三个回调所在的块级作用域,互不干扰。

var循环 let循环

PS:只有在调用到块级作用域中变量的时候,才会将块级作用域添加到作用域链中
PS2:三个回调并非在一个块级作用域下被依次声明,而是将块级作用域循环了三次,每次分别声明了自己作用域下的方法。
PS3:知道为什么就知道怎么影响这个块级作用域啦,引用传递可破,可知作用域变量遵循普通变量传递原则。


如何影响块级作用域

PS4:作用域链的非自己部分在函数对象被建立(函数声明、函数表达式)的时候建立,而不需要等到执行,这部分作用域链是静态的;当函数执行时,建立一个自己当次执行的作用域,然后把这个作用域与前面的作用域链关联起来

相关文章

  • JS let/for循环问题/作用域/上下文环境随笔

    setTimeout会把回调放到代码执行完毕后,再做处理,so 所以就不难理解为什么第一张图会打印5个5了,因为不...

  • 【新手向】ES6常见概念初体验

    一、var和let命令 作用域  ES5的作用域只有全局作用域和函数作用域,这会带来很多问题,比如常用的for循环...

  • sample

    一、var与let JS中的块级作用域,var、let、const三者的区别 var是函数级作用域,没有块级作用域...

  • 我的JS笔记 -- 执行上下文

    执行上下文,就是Js执行的时候的一个运行环境/作用域(scope)。执行上下文决定了Js执行过程中可以获取哪些变量...

  • for循环语法

    for循环作用域解析: 设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。for (let i...

  • 整理

    内容 浏览器渲染 执行上下文 js 事件循环机制 this 作用域 new 原型 原型链 防抖&节流 闭包 深浅拷...

  • ES6 学习笔记

    let 和 const 循环语句中,每次循环都会创建一个新的代码块作用域 var a = [];for (let ...

  • 《ES6标准入门》学习笔记 - let、const、var

    let声明的变量只在当前作用域有效,var声明的作用域,在全局范围内都有效 在循环中,let声明的变量,只在循环体...

  • JS——闭包是什么?用处如何?

    简介作用域链、执行上下文概念 处于活动状态的执行上下文环境只有一个。 作用域最大的用处就是隔离变量,不同作用域下同...

  • ECMAScript6 新增语法

    let 作用域在代码块 用在for循环里面 在作用域内变量重名报错 没有变量提升 死区 函数

网友评论

      本文标题:JS let/for循环问题/作用域/上下文环境随笔

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