在大多数计算机语言中,{}这样一对花括弧叫一个块级作用域,也就是一个执行环境。在一个执行环境中,执行环境内部的变量在作用域外部式无法被访问到的。执行环境内部倒是可以访问外部的变量。
但由于JS中没有块级作用域,只有函数作用域。所以类似于像for(;;){ }这样的作用域,实际上它还是在它的上层作用域之内,如果它上层作用域是global或window,那么实际上这个for循环还是在全局作用域下。

所以,在典型的JS面试题中出现的例子:

const Greeters = []
for (var i = 0 ; i < 10 ; i++) {  Greeters.push(function () { return console.log(i) })
}
Greeters[0]() // 10
Greeters[1]() // 10
Greeters[2]() // 10复制代码

由于,此处默认for语句是在全局作用域下,且for循环并不会生成块级作用域,因此,var声明的i变量也就自然在全局作用域之下,在for循环中又出现了一个匿名函数,这个匿名函数倒是有自己的函数作用域。所以,事实上,这个匿名函数先是写好放在那里,还没有被外部声明调用,它就仅仅地待在那里,当外部声明一个Greeters0想要调用这个函数作时,由于i是在全局作用域被var声明出来的,i已经事先被fior语句循环到等于10了,i=10已经事先固定地保存在全局作用域之中不动了。程序再才来调用的这个函数内部的i。这时,函数只需要去全局作用域环境去找到那个事先已经被固定下来的i=10的那个i就行了,所以,无论调用多少次,它只会去调用那个事先已经循环完毕,并被放入全局作用域下i=10那个i。换句话说,for循环语句的那个{}相当于可以视为没有写。

那么如何解决这个问题呢?

又因为JS中var来声明变量时,var声明出来的变量是在当前作用域环境之下, let声明出来的变量也是在当前作用域之下。不一样的是:let可以把类似于这种JS里面不是块级作用域的作用域(例如for(;;){})变成一个块级作用域,而var不会。并且var可以多次声明同一个变量名,而let不行

var a = 5;
var a = 3;
let b = 2;
let b = 4;
console.console.log(a);
console.console.log(b); // Identifier 'b' has already been declared复制代码

所以,我们可以用ES6的语法let来创建一个块级作用域。

const Greeters = []
for (let i = 0 ; i < 10 ; i++) {  Greeters.push(function () { return console.log(i) })
}
Greeters[0]() // 0
Greeters[1]() // 1
Greeters[2]() // 2复制代码

此时,从外部去调用由于用let每创建一个i,就会去执行一遍内部的匿名函数,并保存起来push进数组Greeters[]里,当你想要调用某一个数组里的函数时,就直接Greetersi 调用对应的数组函数并console.log出当前的i了。

转载于:https://juejin.im/post/59c14d24f265da0672283a75

关于JS中for循环时,作用域问题和this指针指向的总结相关推荐

  1. js中的循环(跳过(continue)和中断执行(break))

    js中的循环(跳过(continue)和中断执行(break)) js循环中可以在循环时是可以中断后续执行和跳过的 看下面这个栗子 //计算1~100之间的和 //我们没有学习过循环之前,使用的做法, ...

  2. js中的for循环如何跳出,js中for循环的两种语法

    js几种for循环的几种用法 谷歌人工智能写作项目:小发猫 js,for循环是怎么运行的? typescript有哪些变化. 最普遍的介绍:for循环是JavaScript中最常用的循环,标准for循 ...

  3. JS中for循环里面的闭包问题的原因及解决办法

    JS中for循环里面的闭包问题的原因及解决办法 参考文章: (1)JS中for循环里面的闭包问题的原因及解决办法 (2)https://www.cnblogs.com/ZinCode/p/555190 ...

  4. JS中在循环内实现休眠(for循环内setTimeout延时问题)

    问题描述: 想要在js中用setTimeout实现这么一个功能:每隔一秒输出一个数字.我们的js代码大概是这样的: for(var i = 0; i < 3; i++) {setTimeout( ...

  5. 聊一聊 JS 中的循环引用及问题

    本文主要从 JS 中为什么会出现循环引用,垃圾回收策略中引用计数为什么有很大的问题,以及循环引用时的对象在使用 JSON.stringify 时为什么会报错,怎样解决这个问题简单谈谈自己的一些理解. ...

  6. js中for循环调用回调函数,一直循环最后一个

    js的for循环中使用回调函数,获取到的值总是最后一个值?_MLAY-CSDN博客_js 循环回调函数

  7. 利用JS中的循环语句来实现正方形、长方形、平行四边形、三角形、菱形、空心菱形。

    利用JS来制造图形 代码 1.正方形 2.长方形 3.平行四边形 4.三角形 5.菱形 6.空心菱形 7.效果图 总结 代码 1.正方形 代码如下(示例): <script>for (va ...

  8. js中for循环嵌套

    首先我们的for循环单个就是我们将内容全部输出出来执行的条件 1.首先声明初始值 2.设置条件 3.执行代码块 4.执行i++ 代码如下, <button type="button&q ...

  9. js中for循环作用域的问题(变量提升)

    for循环定义的变量不管里面有多少函数,变量在里面的所有函数里面都是可以取到的. js的变量提升(var是全局变量,同时只在定义的函数方法可以理解为局部变量) var在for循环里面定义的变量其实也是 ...

最新文章

  1. Logstash 使用fingerprint filter过滤重复数据
  2. struts 修改拦截器修改返回值_关于struts2简单的介绍与示例
  3. Centos7 amp;amp; Docker amp;amp; Jenkins amp;amp; ASP.NET Core
  4. java session 生命周期_Java中httpsession生命周期
  5. DayPilot——10分钟内用于ASP.NET MVC的AJAX每月事件日历
  6. Hadoop 环境准备
  7. Matlab绘制图像后在指定点绘制坐标线以及标注变量
  8. Modown V1.9 WordPress资源素材付费下载Erphpdown主题模板原版
  9. MySQL随机生成六位数验证码
  10. excel 置信区间 计算_正态分布 excle(Excel中用什么函数可以算置信区间,怎么算啊?)...
  11. WLAN RTT (IEEE 802.11mc)
  12. python爬取app store的评论_用python爬取苹果官网店铺
  13. 不要把精力浪费在“吃瓜”上
  14. App Store评论优化,让你的APP评论上涨
  15. 可胜任任何网吧技术主管的绝招
  16. 具备听力保护作用耳机有哪些、不伤耳骨传导耳机排名
  17. 714. 买卖股票的最佳时机含手续费(CPP)
  18. java 随机生成英文名_java随机数Reandom(简单介绍)
  19. c语言编写计算ackerman函数的递归函数ack(n,x,y),第六章函数与宏定义实验报告二...
  20. 使用Aura.Router在PHP中进行Web路由

热门文章

  1. 百度推送管理插件3.4.9Pro
  2. HTML在线颜色代码选取器源码
  3. linux系统输入法怎么安装教程视频教程,Linux怎么安装中文输入法
  4. 有关ArrayList的toArray()方法的一些探究
  5. 自动采集壁纸的微信小程序
  6. Iirf安装配置(图文)
  7. mysql-bin.000001文件的来源及处理方法[转]
  8. jQuery教学-简单好用的视差滚动特效Parallax Effect
  9. 有关linux用户和用户组管理的知识详解
  10. PHP无限极分类生成树方法,无限分级