let const 与var的区别

es6里面的一些新特性还是很好用的,但是有的时候看文档会带来一些疑惑。let、const这两个东西和var到底有哪些不同呢?下面咱们结合一些小例子给大家展示一下。

首先来了解一下let与var的区别,主要有一下三点:

第一点,var在javascript中是支持预解析的,而let不支持预解析,代码如图:

执行结果如图:

结果未报错,下面将var换成let,代码如下:

执行结果:

错误提示为:Uncaught ReferenceError: a is not defined,翻译成中文大概意思就是a未定义。这与undefined是不同的,undefined是未赋值,但已经定义了。

第二点:var可以重复定义同一个变量,但是let不可以,看代码:

执行结果如图:

结果没有报错,将var换成let:

执行结果为:

错误信息为:Uncaught SyntaxError: Identifier 'a' has already been declared。翻译为中文,意思是a已经被定义。

第三点:let可以形成块级作用域,在es6之前javascript只有函数作用域,没有块级作用域。那在es6之前我们是怎么实现块级作用域的呢?有朋友已经猜到了,立即执行函数表达式,简称IIFF。看代码:

执行结果为:

可以看到通过一个立即执行函数表达式,我们实现了一个局部作用域或者块级作用域,但是有了let之后就不需要写这样的代码了,代码修改如下。

执行结果:

可以看到两者实现的效果是一样的。

下面看一道经典面试题:

说出以上代码的执行结果,并解释其原理。将其改造为,依次输出0,1,2,3,4

首先上面的代码执行结果为:每隔200ms依次打印5,一共打印5次。

结果为什么是这样的呢?这里面涉及里javascript里面的两个知识点,作用域和定时器setTimeout回调函数异步执行。这段代码用var声明了一个全局变量i,循环执行完成之后,i变为5,此时javascript主线程空闲,异步回调队列中的函数依次被eventloop放进主线程执行,因为此时的i已经变为了5,所以打印了5次5。

以上便是这道题目的前两点的解析。那第三点,该如何改造代码呢?

明白了原理就好改造了,既然定时器的回调函数中的i每次都是从全局作用域中取值,能不能在循环的时候将其放到局部作用域中呢,当然可以看代码:

执行结果为:

那这些和let有什么关系呢?回忆一下let和var的第三点不同,let可以生成局部作用域,代码再次改造:

执行结果为:

以上便是let和var的不同,如果大家还有补充欢迎留言。

下面是const与var的不同,以上三点完全适用const,但是const与let或是var还有两点不同。

首先是第一点,const是用来定义常量的,常量定义之后是不允许改变的。看代码:

执行结果:

错误提示为:Uncaught TypeError: Assignment to constant variable.意思是常量已经赋值了。

这里有一个小坑,看如下代码:

来看看执行结果,看看和你心理预期是否一致。

没有报错?为什么 ?因为a的值并没有改变,依然指向刚开始赋值的那个对象,并为重新赋值,如果将a重新赋值,就会报错了。大家可以试试。用const定义的常量只要是引用类型数据,改变这个引用类型数据的结构或属性,都是允许的。引用类型包括哪些呢?数组和对象。

第二点是用const定义常量必须赋值。不赋值的话,没有任何意思,所以报错,看代码:

执行结果为:

错误提示为:Uncaught SyntaxError: Missing initializer in const declaration。意思是缺少初识值。

以上便是let const 和var的区别。大家有不明白的或者有补充的可以给我留言。

原文发布于微信公众号 - nodejs全栈开发(geekclass)

原文发表时间:2018-02-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券