let var const

作用域

在es5中,只有全局作用域,函数作用域。在es6中出现了块作用域。
函数作用域指变量在一个函数开始到结束都可以被访问到。

块作用域

以大括号{}为标识确定块作用域。
在es5中使用匿名立即执行函数表达式,在es6中直接引入了块作用域这个概念,代替了匿名立即执行函数表达式。
let 和const 声明的变量有块作用域,而var声明的变量没有块作用域。
块作用域使得内部块的变量无法被外部块访问,开发人员就可以在内外部块中声明相同名字的变量。避免了内外部块的变量互相影响。

const

const通常用于定义常量。它需要在声明时就进行赋值,否则会报Missing initializer in const declaration错误。const定义的值不能被修改,它保存的是一个地址,如果是普通变量,就是普通变量的地址,如果保存的是引用类型变量,保存的就是指向对象的指针的地址。
这里涉及到堆空间和栈空间。普通变量在栈空间开辟空间,然后存储值。引用变量在堆空间开辟空间,然后在栈空间中保存堆空间的地址,引用变量实际是存储在堆空间的。所以使用const设置一个常量为引用类型时,保存的是堆空间中的地址,地址不变,但地址中存储的内容可以改变,这时就相当于声明了一个指针。
如果要真正保持引用对象保持不变,可以使用object.freze()方法。冰冻对象跟复制对象一样,都存在深浅两种。

let

经常能够看到下面的例子:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

这是一个陷阱。
由于var没有块作用域,所以每次循环的时候实际操作的都是同一个i,最后访问的也是同一个i,它并不是我们想要的效果。
正确的方法是将var改为let,这样每次循环都会新生成一个i,游览器会记住上一个i值,这能达到想要的效果。

重复声明?

在同一个作用域内,不允许重复声明一个变量。这会报错。

变量提升?

  • 什么是变量提升?
    变量提升让我们能够在变量声明前使用变量。游览器在编译时,会先把所有的声明提升到前面。变量提升之后,如果变量是被使用后才声明赋值的,在访问这个变量时也不会报错,只不过他是undefined。
    表面上看这个规则减少了错误,但是同时也造成了许多不必要的麻烦,正确的方法应该是变量先声明后使用,这样开发者更加心中有数。
  • let,const,var都有变量提升吗?
    只有var存在变量提升,let,const都没有变量提升,这也是es6进步之处。

能否在块中写函数?

在es6中规定了可以将函数写到块中,等同于使用var声明变量,存在变量提升,块作用域的函数声明会提升到全局作用域或者函数作用域头部。如果在块中有个函数f(){},在提升后为f=undefined;

TDZ

暂时性死区。
由于let 和const不存在变量提升,即使在代码后面对某一个变量进行了声明赋值,但是在声明赋值代码行之前,这个变量都是不可使用的,使用就会报错reference error,这就是暂时性死区。
规范的方法还是先声明后使用。

全局变量和顶级对象属性

  • 顶级对象
    在游览器中顶级对象是window,在node中顶级对象是global。
  • 全局变量是顶级对象的属性(以下是在游览器环境)?
    在es5中,全局变量就是顶级对象的属性,所有全局变量都可以通过window. 访问。这就导致无法在代码编译时发现全部的错误,因为有些变量可能是通过window. 动态声明的。
    在es6中,使用let,声明的变量就不再是顶级对象的属性,无法使用window. 访问到。es6开始逐渐剥离全局对象和顶级对象。但是使用var声明的变量依然是顶级对象的属性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值