这样理解Javascript中let/var区别
自从ES6引入了变量定义的新关键词const和let后,不少人都会关系到底跟之前的var关键词有何区别,在今后的js开发中怎么使用;在写这篇文章之前也是看了不少教程,讲解的都是差不多的意思,但是还是很难理解,在写下这篇文章前通了,所以记录下来。
首先const比较容易区别开来,一句话,const就是定义不变的值,一些常量等不需要改变的值;比较难以理解主要集中在let和var的区别,当你发现有了let这个新关键词定义变量的时候,去百度相关教程,几乎所有的教程文字视频都在告诉你let有块级作用域,而var没有。是不是一脸懵逼,什么块级作用域,区别体现在哪里?
那到底什么块级作用域,怎么才能比较好理解这二者的区别,怎样才能通俗易懂的理解差别?
Javascript的块、块级作用域
JavaScript的块简单的来说就是用大括号”{}“,包裹起来的代码块,常见的if里的代码块,for里的代码块都是块。你也可以认为的将一段代码用大括号括起来就是一个块了。
知道了块,那么块级作用域自然好理解,就是在这个代码块里是个小天地,在这里面的定义的量怎么改变都不会影响到外面同名变量的值。
实例解释
还是没有理解吧,看一个在let出现前,一个比较难以理解的案例。当有多个按钮(如5个),对这些按钮都绑定点击事件,点击其中一个打印其索引值,我们会这么写:
HTML部分:
<button class="clicked">欠点</button> <button class="clicked">欠点</button> <button class="clicked">欠点</button> <button class="clicked">欠点</button> <button class="clicked">欠点</button>
js部分,获取按钮集合,依次绑定点击事件源码如下,当点击其中一个按钮 执行点击事件,会发现无论是哪个打印都是”5″
var clickedEl = document.getElementsByClassName('clicked'); for(var i= 0;i< clickedEl.length;i++){ console.log(i); // 0,1,2,3,4 clickedEl[i].addEventListener('click',function(){ console.log(i); // 打印了 5个 5 }) }
代码详细以及执行结果截图如下面的:
这里的问题相信很多初学JavaScript的童鞋们都会比较费解,不知道怎么去获取当前被点击的按钮的索引值,也会很费解为什么每个按钮点击的结果都是相同的。明明i从0到4都获取到了,最后却是打印5。这里就是因为var的申明的变量没有块级作用域的概念,造成了没有得到我们想要的结果。
处理方式
在let申明(ES6)出现之前的处理方式是将循环值“i”作为参数传入一个立即执行的匿名函数(闭包)来解决此问题:
var clickedEl = document.getElementsByClassName('clicked'); for(var i= 0;i< clickedEl.length;i++){ console.log(i); // 0,1,2,3,4 (function(ii){ //闭包处理 立即执行匿名函数(function(){...})() clickedEl[ii].addEventListener('click',function(){ console.log(i); // 当前点击的索引 }) })(i) //将i 作为参数传入匿名函数 }
而ES6到来之后,我们将for里的var变成let申明时,结果也是我们想要的:
var clickedEl = document.getElementsByClassName('clicked'); for(let i= 0;i< clickedEl.length;i++){ //let申明 console.log(i); // 0,1,2,3,4 clickedEl[i].addEventListener('click',function(){ console.log(i); // 打印了 被点击的索引值 }) }
这个例子从足见let和var的区别之处,可能看了实例还是很难理解为什么一个块级作用域会影响这么大,可以这么理解,for循环是执行多次相同函数的过程,而每次执行都是一个块。
var/let申明for循环区别之处理解
当我们要一个函数执行多次的的时候我们会用到for循环,而var申明的情况如下:
for(var i= 0;i< 3;i++){ console.log(i); // 0,1,2 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i); }) }
也就是里面的代码执行了三次,可以理解为下面的三个块:
// i = 0 一个块 { var i = 0; console.log(i); //0 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i); //2 }) } // i = 1 一个块 { var i = 1; console.log(i); //1 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i); //2 }) } // i = 2 一个块 { var i = 2; console.log(i); //2 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i); //2 }) }
理解:因为var没有块级作用域概念 所以在一个新的块级里重新定义i时,改变的是全局的i值;clickedEl执行函数 click 时 i 已经最终的改变值(2)
let申明for里的变量时情况:
for(let i= 0;i< 3;i++){ console.log(i); // 0,1,2 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i); }) }
同样可以理解为三个块:
// i = 0 一个块 { let i = 0; console.log(i); //0 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i); //0 }) } // i = 1 一个块 { let i = 1; console.log(i); //1 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i);//1 }) } // i = 2 一个块 { let i = 2; console.log(i); //2 var clickedEl = document.getElementById('clicked'); clickedEl.addEventListener('click',function(){ console.log(i);//2 }) }
理解:因为let有块级作用域 各个块里的i相互不影响,所以每个块里的i是独立的,打印的值就是块里的的值。
这样的理解是不是就比较好理解了,明明就是一个单词之差,结果却是天壤之别,将for的循环拆开为多个块就比较好理解了不是。另外在用闭包处理的时候,原理也是因为函数有作用域,将循环的i值作为函数参数传入匿名函数,达到不受全局变量的影响效果。
① 本站源码模板等资源SVIP用户永久不限量免费下载
② 所有资源来源于网络收集,如有侵权,请联系站长进行删除处理。
③ 分享目的仅供大家学习和交流,请不要用于商业用途,否则后果自负。
④ 如果你有源码需要出售,可以联系管理详谈。
⑤ 本站提供的源码、模板、插件等等资源,都不包含技术服务请大家谅解。
⑥ 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需。
⑦ 在您的能力范围内,为了大环境的良性发展,请尽可能的选择正版资源。
⑧ 网站资源绝不做任何二次加密或添加后门(原版加密除外)
- 需要积分的资源怎么下载?
- 您可以注册后签到等活跃动作获得积分,积分可下载,也可充值升级等级免费下载。
- 源码模板等文件安全吗?有没有后门病毒吗?
- 站内资源标有“已测试”标签的资源源码,表示已经在本地安装测试调试过才分享出来的,可以保证一定的安全;若不放心可以自行下载模板资源后使用D盾等查杀工具扫一遍确认安全。
- 本站网站模板等源码提供安装服务吗?
- 本站资源收集于网络并分享出来共同学习,不提供免费安装服务,模板源码安装等需要有一定熟悉度,小白用户可以下载资源后雇人安装调试。