前言
上篇文章咱们讲了ECMAScript6的历史演进,讲了它是怎么来的,以及一些花边新闻。那么这次咱们继续来讲讲ES6里面的变量 let 和 const。当然了,这篇文章仍然是以扫盲为主,科普为辅。各位童鞋们,搬好小板凳。
接下来,接下来正文从这儿开始~
首先在说变量之前,大家一定要想明白一件事,那就是你觉得为什么要出ES6?刷存在感?也不一定,它肯定有这方面的因素。实际上来说,任何东西都有它的缺陷和不足,可能前几年的时候,你觉得这个东西真棒,全世界最好的就是它了。但是等再过几年,你再看呢,论性能不如C语言,工程性不如Java,论搞怪还不如Python,反正怎么看都不行了。说白了,语言必然有个迭代的过程,它总有一些自己的问题,咱们先来说说看,JavaScript它原本的var变量,到底问题出在哪儿。
实际上,JS这门语言是我用过的十几门语言里最Low的一个。尤其体现在var上,它有几个问题:
1.可以重复声明
var a = 20;
var a = 18;
console.log(a);
18打印出来了,控制台没有报错,也没有警告。
如果你认识玩Java的,你问问,“ 唉Java哥,请问我这么写,你觉得靠谱吗?”
int a = 20;
int b = 18;
我可以负责任的告诉你,人家能喷死你信不信。“ 就这破写法,你怎么定义两次啊?” 对吧,这在别的语言是无法想象的。
所以,第一个问题就是可以重复声明,可能你第一个接触的语言就是JS,勉强还能接受。
第二个问题就是:无法限制修改
什么意思呢?就比方说举个最简单的例子,咱程序里边总有那么些东西是永久不变的,一直是保持一个值。如果你知识面广点的,也许你就知道了,我说的是常量。就比方说最简单的PI=3.1415926,咱就别说人类的历史,咱就说说你这仅有几年的前端生涯中,你觉得PI会发生变化吗,不太可能吧。在很多语言中都有常量的概念,而JS没有。
为什么Java是全世界最流行的一门编程语言,没有之一?越是简单容易的语言,实际上来说他并不严谨。
然后第三个问题,没有块级作用域。
当然如果你是JavaScript出身,可能你对块级作用域不是特别的了解。如果你在问问Java哥,你们Java里有没有块级作用域啊,人家会告诉你,那是吃饭的家伙,肯定有啊。
先简单的说说什么叫块级作用域
{
}
这就叫块,拿这个花括号括起来。
还有if 和 for 语句:
if ( ) {
//其实这里定义的变量,跑出去之后就访问不到了。
}
for ( ) {
}
可能你听完觉得说,var没有块级作用域,没有就没有吧,人生最重要的就是开心嘛。其实不然,等你听完我讲的之后,你会觉得块级作用域特别重要。
你比如说:
if(true){
var a = 20;
}
console.log(a);
它居然能访问到,一点问题都没有。
那么我就不墨迹了,接下来我们直接进入正题,其实ES6里面出现了两个新的定义变量的方式,一个叫做let 一个叫做const。首先let 和const拥有一个共同点,那就是不能重复声明。
举个例子:
let a = 20;
let a = 18;
console.log(a);
然后到浏览器里访问,发现报错了:
Uncaught SyntaxError: Identifier 'a'has already been declared.
说这个变量已经声明过了。
就拿我现身说法,在我写过的复杂程序里面,使用let就帮过我忙了,报错信息说变量被重复声明了。当然有童鞋会说,闰土,那个var用严格模式也能做到。那是另一个话题,咱这暂且按下不表。
然后,const也是同样的道理,你重复声明过后,浏览器不理你,控制台默默地告诉你,报错了,和let报的是同样的错。
然后,let是变量,可以修改的。而const是常量,不可以修改的。
举个例子:
let a = 20;
a = 18;
console.log(a); // 18
如果是const,结果就报错了:
Uncaught SyntaxError: Assignment to constant variable.
说白了,就是不能对常量重新赋值。
然后第三个就是块级作用域。
if(true){
let a = 20;
}
console.log(a);
然后去浏览器控制台里看,发现报错了:
Uncaught ReferenceError: a is not defined.
说a没有定义,很简单,我这个a只在花括号的作用域里起作用。当然,const也是如此。
你知道,一门语言推出新的版本,肯定是要解决掉以前的一些问题,ES6也不例外,就是在填自己的坑,当年自己也没想到这方面。
那么接下来问题来了,块级作用域有什么用?
举个例子:
window.onload = function() {
var aBtn = document.getElementsByTagName('input');
for(var i=0;i
aBtn[i].onclick=function(){
alert(i);
}
}
}
结果弹出来都是3。那以前是怎么解决的呢
给他封一个封闭空间,利用函数作为一级作用域,函数本来就有作用域,利用函数赋值了一份。
for(var i=0;i
(function(i){
aBtn[i].onclick=function(){
alert(i);
}
})(i)
}
原生的var,只有函数才能限制它的作用域,它需要通过这个来解决问题,var只认函数这个作用域。
当然,现在看感觉这样有点太麻烦了。让我们来看看用了let 之后的效果
for(let i=0;i
aBtn[i].onclick=function(){
alert(i);
}
}
当然我们这个for循环本身就是一个语法块,它就是一个作用域。在浏览器里你会发现,妥妥的弹出了,0,1,2这三个索引。
后记
对于大型的项目来说,做出来真不难。难在哪儿,难在你能不能把这个项目管理好。说白了人多嘴杂的,可能这哥们这么写,那哥们那么写,几下倒腾过来就乱套了,比方说,我这有个a,你那有个a。如果是块级作用域,那就好办了,我声明的变量在块级作用域内能访问到,出去了就访问不到了。那么你那有个a,我这有个a,就没事了,互不影响,更容易避免问题。
所以说,咱们现在看到了ES6的一个特性,关于let 和 const。当然如果let 和const 在你那边的浏览器会报错,说明你的浏览器版本低,那么请升级你的Chrome,Firefox等浏览器。
大话前端系列文章较长,未完待续。
领取专属 10元无门槛券
私享最新 技术干货