ES学习之var,let,const的比较

作为前端,不管是菜鸟还是大牛,都时时刻刻在使用var,let,const。作为前端入门级菜鸟选手,决定整理一下自己的知识。以下内容是小沐在查看很多文章资料后总结出来的,可能有地方和一些文章有相似之处,也有不准确或者不合适的地方,欢迎指正,谢谢。

var

对于var,特点总结如下:
1.可以不初始化,值为undefined
2.可以重复声明
3.声明的全局变量为全局对象的属性
4.作用域:函数作用域
5.存在变量提升现象

关于变量的声明与不声明的区别(针对于var):

给一个未声明的变量赋值会隐式创建一个全局变量(会造成代码污染)。以下是一些区别:
(1)声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的。
(2)声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作时才被创建。
(3)声明变量是它所在上下文环境的不可配置属性,非声明变量是可配置的(例如非声明变量可以被删除)

var声明的全局变量属于全局对象的属性,即意味着我们可以通过window.变量名的方式访问到。

作用域引发的变量提升

var声明的变量作用域限定为当前执行位置的上下文,即 一个函数的内部(函数内)或者全局(函数外),通俗点讲,就是从变量声明处开始向前后两个方向扩散,直到触碰到函数的边界。
你看,这么大的一个作用域,导致的结果就是在函数一开始的时候就要去创建它,无论var的声明语句是在函数里面的一个if块还是for循环中,都是如此。由此产生了变量提升的现象。
变量提升只用于变量声明的提升,对于赋值来说,原来在哪现在还在哪
(此处对变量提升不做详细介绍,我们的重点是var,const和let的比较)

循环中的乱象(变量共享)

首先看一下我们平时的简单循环:
    var talk = ["嗨!宝贝", "相信我", "这绝对是一个惊喜!","哈哈哈,有没有吓到"];    	
    for (var i = 0; i < talk.length; i++) {     		 
      console.log(talk[i]);    	
    }
这段代码自然是没有什么错误的,正如我们料到的一样,输出的是上面数组中的全部元素。
那我们再来看看下面这一段:
var talks= ["哦我亲爱的宝贝", "不要为那只愚蠢的土拨鼠生气了!", "你很好不是吗"];    	
    for (var i = 0; i < talks.length; i++) {      		 
      setTimeout(function () {        		
        console.log(talks[i]);      		 
      }, i * 1500);    	
    }
是不是还是会输出talks里面的所有元素?哦no!!不是的!!运行之后输出来的是三个undefined!!!让我们来看看问题出在哪里。
for循环中有一个定时器函数setTimeout,里面有一个回调函数function。循环和timeout回调共享一个变量i,当三次循环结束时,事实上回调还未被触发,此时i已经为3了。然后此时回调才开始执行,输出talks[3]即undefined。

let

对于let,特点总结如下:
1.可以不初始化,值为undefined
2. 可重复声明
3.声明的全局变量不是全局对象的属性
3.作用域:块级作用域
4.无变量提升现象

变量的声明:

重复声明报错: Uncaught SyntaxError: Identifier 'a' has already been declared
let声明的全局变量不属于全局对象object中,即不能通过window.变量名方式访问

作用域与变量提升

let声明的变量作用域为块级,即在代码块中有效,如if,while等,同样与var相似的是 包含定义它的块以及任何包含的子块中。
关于let的变量提升,在与var的变量提升相比,是没有这个现象的,因为我们在声明它之前使用它是会报错。不过看了一篇文章( https://www.jianshu.com/p/0f49c88cf169 )解释到 let也是有变量提升的,只不过有一个暂时死区。
对于let的变量提升,答案不一,小沐也搞的有点晕,总之是和var的变量提升不一样就是了,所以这里先不做介绍(待小沐弄明白以后再来讨论)。因为我们的重点仍然不是解释变量提升,而是比较这三个关键字。

for循环变量共享问题的解决

对于for(let i...)这样的循环,在每次循环迭代的时候都会为i创建一个新的绑定,即保持了一个闭包,每个闭包都会保存每次循环的i值,而不是最后的一个值。

const

对于const,特点总结如下:
1.必须初始化
2. 可重复声明
3.作用域:块级作用域
4.不存在变量提升现象
5.声明的基本数据类型值为常量,之后值不可修改,声明的数组等对象可以进行修改

const和let声明的变量很类似,不同之处在于变量的声明和初始化必须一起进行,且之后值不可随意修改
只声明不赋值报错: Uncaught SyntaxError: Missing initializer in const declaration

对于声明数值的可变性,有以下两种情况:
当变量类型为number,string,boolean,null时,数值是常量,即在初始化之后不允许修改,否则报错 Uncaught TypeError: Assignment to constant variable.
但是当变量为对象,数组时,其内容可以修改,因为对象,数组等变量存放的是地址,地址不允许修改,但是地址里面存放的内容是可以修改的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值