ES6+ 学习 ----- let 和 const 在for 循环中的使用

  在ES6 的规范中,多了两个声明变量的关键字: let 和const。初次学习的时候,只记住了 let 声明的变量只在for 的循环体中有效,循环结束后 变量就消失了, 同时const 也可以在for 循环中声明变量,但是不能用于 常规的for 循环中。所谓的常规for 循环就是for(let i =0; i < 10; i++) 的格式。今天重读了一遍Understanding ECMAScript 6, 算是明白了。

  当我们在使用for 循环的时候,每一次的迭代都会重新声明一个变量。像for(let i = 0; i < 10; i++); 这样使用时,i 变量声明了10次,只不过每一次迭代改i 赋值不一样而已,并且变量只在循环体中使用。 我们可以这样理解: 第一次迭代的使用,声明了一个变量i, 赋值为0, 0 < 10, 然后执行循环体,执行完之后i++ 变成了1. 这一次迭代就结束了,这个i 的使命就完成了。然后进行第二次迭代,这时重新声明一个变量i, 不过这次给他赋值为1,1 < 10 继续执行循环体,然后加1. 这次迭代又结束了,这个i 也完成了使命,消失了。第三次迭代进行同样的操作,声明一个全新的变量i,执行循环体之类的,直达整个循环结束。

  对于for 循环来说,每一次的迭代都是重新声明一个全新的变量i,只是赋的值是上一次迭代完成时的值,这样的话,循环体内获取到的i, 每次也都是全新的变量i,而不是像使用 var 声明时得到的是全局变量,并且,每一次迭代完成后,i 变量就消失了。举个简单的例子,大家一看就能明白。

let funs = [];

// 使用var 声明循环变量i
for (var i = 0; i < 10; i++) {
    funs.push(function(){
        console.log(i);
    })
}
// funs.forEach(item => item());  // 输出10个10

// 改为使用let 声明循环变量
let funss = [];

for (let i = 0; i < 10; i++) {
    funss.push(function(){
        console.log(i);
    })
}

funss.forEach(item => item());  // 输出0, 1, 2, 3, 4, 5, 6, 7, 8, 9

  除了常规的for 循环之外,还有for-in 和for-of 操作, 原理都是一样的,他们每一次的迭代都是重新声明一个全新的迭代对象,而不是给原来声明的迭代对象赋新值, 循环体内获取到的都是当前迭代对象的值。

let funcs = [];
let arr = [1, 2, 3];
// for-in 循环, 数组是不建议使用for-in ,这里只是简单的演示
for (let key in arr) {
funcs.push(function() {
        console.log(key);
    });
}
funcs.forEach(function(func) {
    func(); // 输出0, 1, 2
});

// 使用for-of
funcs = [];
for (let key of arr) {
    funcs.push(function() {
        console.log(key);
    });
}

funcs.forEach(function(func) {
    func(); // 输出1, 2,3
});

  现在看一下const, const 也可以使用在for循环中。最简单的就是把上面的三个for 循环中的let 都转换为const.  for (const i = 0; i < 10; i++) {};   for (const key of arr) {} , for (const key in arr) {} . 这时你会发现第一种常规for 循环报错了。看一下第一次迭代就知道了。声明了一个 变量i, 赋值为0。 但这里使用const, 也就意味着i 在声明之后,就不能再改变了。好了,0 < 10, 执行循环体,然后  加1,报错了,i 不能变化了。一次迭代都没有走完,就报错了,说明,在使用常规for 循环时, const  不能用来声明变量。

  再来看一下,for-of, for-in, 没有问题,因为每一次的迭代都会声明一个全新的key, 所有的赋值都是给一个新的变量赋值,而没有改变原来的值。那使用let 和 const 有什么区别吗? 当然有了,还是在于const  声明的变量不能重新赋值了,所以如果for-in 或for- of 中使用const 声明了变量( 如key), 循环体中,就不能给key 赋新值了,如果使用let ,那就无所谓了,想干什么就干什么。只不过for-in 或for-of 中,我们很少改变key 值,所以他们在实际使用时就没有什么区别了。

  这里再简单说一下const.  当声明一个变量时,称之为binding(绑定)。在一个作用域中声明变量的时候,相当于这个变量绑定到了该作用域中,对于const 声明的变量来说,它的绑定更近了一步,直接绑定到一个值上。const name = "sam"; 变量name 直接绑定了一个值"sam"; 如果再更改这个绑定,就报错了。那么怎么才算更改绑定呢?就是重新赋值。name ="json" 报错了。如果name 刚开始绑定的是一个对象呢? const name = {a: ‘b"}, 还是一样,重新赋值就会报错,name={} 报错。但如果改变对象的值,则没有问题 name. a = "c"; 因为没有改变绑定。name 绑定到一个对象,就相当于我们的地址 对应的一个真实的建筑物 . const 声明了一个变量,就相当于写了一个地址,比如,北京市东城区长安街, 绑定到一个对象上,那就是故宫了。北京市东城区长安街 绑定到了天安门对象上。那如果更改绑定,就意味着北京市东城区长安街 绑定到别的地方了,比如长城,那谁受得了,本来是想看故宫的,突然变成游长城了。但如果改变故宫呢? 比如故宫今天安排了特别的文艺演出,没有问题啊?故宫还在那地方,按照地址还是到故宫了。

原文地址:https://www.cnblogs.com/SamWeb/p/10659352.html

时间: 2024-08-28 23:50:54

ES6+ 学习 ----- let 和 const 在for 循环中的使用的相关文章

es6学习 -- let和const

在es6中let和const声明的变量都只能在其声明的块级作用域中使用,所谓的块级作用域就是{}这么一对大括号. 为什么需要块级作用域? ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景. 第一种场景,内层变量可能会覆盖外层变量. var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world'; } } f(); // undefined 上面代码的原

ES6学习之Iterator和For...of循环

一.Iterator(它是一种接口,为各种不同的数据结构提供统一的访问机制.Iterator 接口主要供for...of消费) 默认Iterator接口(默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是"可遍历的"(iterable).Symbol.iterator属性本身是一个函数) 部署Iterator 接口: const obj = { [Symbol.iterator]

ES6学习笔记之变量声明let,const

最近用淘宝的weex做了个项目,最近稍微闲下来了.正好很久没有接触RN了,所以趁这个机会系统的学习一下ES6的相关知识. 孔子说:没有对比就没有伤害.所以我们要拿ES6和ES5好好对比的学习.这样才能明白es6是多少的好,积极的拥抱她! 1.let 用let声明的变量,只会在let命令所在的代码块内有效. let的块状作用域 我们来看一个简单的例子: 'use strict'; { let name = 'cloud'; var age = 21; } name;//ReferenceError

ES6学习笔记(一)

1.ES6学习之let.const (1).var.let.const 变(常)量声明 ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景. 在ES6中let就诞生了,实际上它为javascript新增了块级作用域. let只在变量声明时 ,所在的代码块中有效. 由于这一特性,let很适合在for循环中使用. 如下图是一个demo: let声明变量的特点: a:不存在变量提升: console.log(m);//Uncaught ReferenceError: m is

ES6学习一

一项新技术的出现肯定是为了解决一些问题,那么ES6的出现主要是解决了哪些问题?它的出现给我们带来了什么便利?当它没有出现的时候,某些问题怎么处理?ES6的方法和以前的方法比较又有什么不同呢?根据提出的这些问题,我开始了ES6学习之旅. ES6是在ES5的基础上对语法进行了修正以及添加了一些新的功能, 具体修正了哪些语法与添加了哪些新的功能,那就开始学习吧.      let                    ES6新增加了let命令,用于变量声明,与var的用法类似,不同的是所声明的变量只在

我的es6学习笔记

前两个月看了一套es6的教程,现在将当时我做的笔记分享出来,与大家一起分享,我的不足之初也希望大家可以指出来.虽然简单学过一遍,但是我项目中用到的也就const,let,解构赋值,默认参数,箭头函数,promiss,模板字符串差不多这几个吧,其他的还不是很了解.现在再拿出来结合阮一峰老师的书再重新的学习一遍. ES6 npm install babel-cli -g npm install babel-cli babel-preset-es2015 --save-dev babel es6.js

es6学习笔记初步总结

es6学习笔记初步总结 1. let.const 和 block 作用域 在ES6以前,var关键字声明变量.无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部).这就是函数变量提升例如: let 关键词声明的变量不具备变量提升(hoisting)特性 let 和 const 声明只在最靠近的一个块中(花括号内)有效 当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING const 在声明时必须被赋值 否则报语法错误SyntaxError

ES6学习笔记之Promise

入职百度EFE团队实习已经三周了,实习中接触到了生产环境的技术和开发流程,大开眼界,和自己在学校接小作坊式项目是很不一样的体验.其中一个很大的感触是,ES6早已不是“选修”的尝鲜技术,而是已经全面普及应用.非学不可的“必修”技术,看来该版本新加入的特性的确解决了前端项目开发中的痛点,有利于提升开发效率. 说到ES6,像let,const,箭头函数这些特性简单易懂,很快就实现了无痛上手:然而Promise不是那么直观,项目文档里大量的“返回一个Promise对象”让初接触这一概念的我一度懵比,于是

关于ES6学习心得

已经不记得什么适合开始学习阮老师的<ECMAScript6入门>,中途一直断断续续的看,到目前了也是没完全看完,很是惭愧!刚好借"儿童节"写个小结. 看来我真的不适合自学,一直都是理论看起来是枯燥了点,做个小总结吧!方便后续继续看,别每次都是从头开始! 1,let和const 声明变量 let 类似于之前的 var  相比较不同的是多了作用域和取消了声明提前的机制 1.1  在 let 作用域外调用 let 声明的变量会报未定义的错误(ReferenceError: a i