es6入门1-- let与var的区别详解

一、前言
二、let与var的区别
1.let 不能重复声明,但var可以
var a = 1;
var a = 2;//不会报错
let b = 1;
let b = 2;//报错
2.let会产生块级作用域,且只在自己的作用域内生效,但var不受限制
ES5 只有全局作用域和函数作用域,那什么是块级作用域?当我们在{}中使用了let或者const时,{}的范围就是一个块级作用域,此时let或const只能在{}中访问,像这样:
{
let a = 1;
var b = 2;
}
console.log(a);//报错
console.log(a);//
或者这样:
if(true){
let a = 1;
var b = 1;
}
console.log(a);//报错
console.log(b);//1
//for循环用var
var a = [];
for (var i = 0; i < 5; i++) {
a[i] = function () {
console.log(i);
};
}
a[1]();//
a[2]();//
a[3]();//
//for循环用let
var b = [];
for (let i = 0; i < 5; i++) {
b[i] = function () {
console.log(i);
};
}
b[1]();//
b[2]();//
b[3]();//
在明白上面2个循环的区别之前,我们先来理一理知识点,我们要知道,for循环中设置循环变量的部位其实是一个父作用域,循环体内部是个子作用域。
在父子作用域中使用let声明同一变量时,对于此变量而言,两个作用域的同名变量其实是互不相关的两个独立变量:
{
let a = 1;
{
console.log(a);//报错,暂时性死域,在let a前面使用a不合法
let a = 2;
console.log(a);//
}
console.log(a);//
}
即便父子作用域都使用了let,子作用域也能正常继承自己非let的变量,父也能读取子作用域非let的变量。
{
let a = 1;
{
//这里使用了let,也是块级作用域,但也能正常访问父块级作用域的变量a
let c = 1;
var b = 2;
console.log(a);//
}
console.log(a);//
console.log(b);//
}
所以下面这个循环输出了三次echo,因为在子作用域中声明的i跟父作用域中的i可以说是完全不同的两个i;
for(let i = 0;i<3;i++){
let i = 'echo';
console.log(i);
};//输出三次echo
但如果你将let改为var,你会发现只输出一次,因为没有了块级作用域,父子作用域共用了一个变量i,第一次循环后,子作用域的i被改为了echo,父作用域中i<3的判断无法通过,所以只输出了一次。
那么回头再看看最初的两个循环,为什么var声明输出了3个5,而let输出了1,2,3呢,尝试去理解,说到底还是块级作用域搞的鬼。
3.let不存在变量提升
console.log(a);//undefined
var a = 1;
console.log(b);//报错
let b = 1;
var a = 1;
function f() {
console.log(a);//undefined
if (false) {
var a = 2;
}
}
f();
var a = 1;
function f() {
var a;
console.log(a);//undefined
if (false) {
a = 2;
}
}
f();
就问你,惊不惊喜?意不意外?

4.let存在暂时性死域
{
let a = 1;
{
console.log(a);//报错
let a =2;
}
}
三、const声明的特点
可以理解为,let的特性const都有,不能反复声明,存在块级作用域,不存在变量提升,也有暂时性死域的特点。
与let区别在于,const声明的是一个常量,一旦声明就无法修改,有个误区需要特别注意,举个例子:
const a = {};
a.b = 1;
console.log(a);//{b:1}
上述代码中我声明了一个常量对象a,但是a对象修改了,并没有报错,这是为什么呢?从本质上理解,const声明的变量并非变量的值不能修改,而是可以理解为变量的指向不能修改。
只是基本类型的数据,键值都在栈内存中,但对于复杂数据类型,变量指向的其实是堆内存中存放值所提供的一个地址。所以我们不能修改复杂数据类型的指向,这样就会报错:
const a = {};
a.b = 1;
console.log(a);//{b:1}
a = [];//这里直接修改了变量a的指向,不允许了。
console.log(a);//报错
四、小总结
let与const的出现对于JS有什么影响或者说好处呢?
我们知道,在ES5环境中只有全局作用域与函数作用域,这也导致我们通过var声明的全局变量直接与全局对象挂钩,而浏览器环境全局对象是window,所以我们随便声明的全局对象都可以通过window访问,很明显,这样的环境很容易造成混乱。
var a = 1;
console.log(window.a)//
而ES6带来的let与const,可以说是宣告天下,从此我全局变量将逐步与顶层对象属性脱离开来,还你一片极乐净土。
当然,ES6中var与function声明的全局变量还是会出现在顶层变量中,但至少现在提供了一种解决方式,JS语言也在成长的越来越好。
番外:
在记录完let与var在for循环中的不同变现,我觉得我解释的不够合理,还是得单独拿出来说下,即使let与var只是做声明这件小事,我在拆分for循环步骤时,发现了一个很有趣的问题,所以深挖了一下。有兴趣可以阅读我的这篇博客:
es6入门1-- let与var的区别详解的更多相关文章
- 大数据入门基础系列之Hadoop1.X、Hadoop2.X和Hadoop3.X的多维度区别详解(博主推荐)
不多说,直接上干货! 在前面的博文里,我已经介绍了 大数据入门基础系列之Linux操作系统简介与选择 大数据入门基础系列之虚拟机的下载.安装详解 大数据入门基础系列之Linux的安装详解 大数据入门基 ...
- ES6,ES2105核心功能一览,js新特性详解
ES6,ES2105核心功能一览,js新特性详解 过去几年 JavaScript 发生了很大的变化.ES6(ECMAScript 6.ES2105)是 JavaScript 语言的新标准,2015 年 ...
- javascript中=、==、===区别详解
javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...
- Go学习——new()和 make()的区别详解(转载)
这篇文章主要介绍了Go语言中new()和 make()的区别详解,本文讲解了new 的主要特性.make 的主要特性,并对它们的区别做了总结,需要的朋友可以参考下 概述 Go 语言中的 new 和 m ...
- JQ的offset().top与js的offsetTop区别详解
一.前言 最近在做一个图片懒加载的插件,就纵轴(Y轴)而言,我需要时时获取图片的上偏移量,好判断是否已进入视图区域,而我所理解的是offsetTop应该是跟offset().top一样的,然后陷入了因 ...
- jQuery height()、innerHeight()、outerHeight()函数的区别详解
参考来源:http://www.jb51.net/article/84897.htm 代码示例(可复制到编辑器直接打开): <!DOCTYPE html> <html lang=&q ...
- JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离
壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...
- 基于Java的打包jar、war、ear包的作用与区别详解
本篇文章,小编为大家介绍,基于Java的打包jar.war.ear包的作用与区别详解.需要的朋友参考下 以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.cla ...
- Android中Intent传值与Bundle传值的区别详解
Android中Intent传值与Bundle传值的区别详解 举个例子我现在要从A界面跳转到B界面或者C界面 这样的话 我就需要写2个Intent如果你还要涉及的传值的话 你的Intent就要写两 ...
随机推荐
- Book : <Hands-on ML with Sklearn & TF> pdf/epub
非常好的书,最近发现了pdf版本,链接:http://www.finelybook.com/hands-on-machine-learning-with-scikit-learn-and-tensor ...
- 关于Socket.IO的知识点记录
最近因为项目的需要,开始学习nodejs,本着js的那点儿功底,nodejs学习起来还是挺快能上手的.随着深入学习,知道了express框架并那它写了一个小功能,作为一个php程序员哈,在expres ...
- cobbler实现系统自动化安装centos
cobbler [epel] cobbler服务集成 PXE DHCP rsync Http DNS Kickstart IPMI[电源管理] 1.软件安装 yum install cobbler d ...
- WSGI协议以及对服务器的影响
下面的内容纯属个人学习心得,如果对于我的观点有疑问,敬请留言,我将虚心向大牛学习. WSGI的全称是WEB SERVICE GATEWAY INTERFACE.WSGI 不是服务器,不是API,也不是 ...
- Android插件化的兼容性(中):Android P的适配
Android系统的每次版本升级,都会对原有代码进行重构,这就为插件化带来了麻烦. Android P对插件化的影响,主要体现在两方面,一是它重构了H类中Activity相关的逻辑,另一个是它重构了I ...
- 在Docker容器中搭建MXNet/Gluon开发环境
在这篇文章中没有直接使用MXNet官方提供的docker image,而是从一个干净的nvidia/cuda镜像开始,一步一步部署mxnet需要的相关软件环境,这样做是为了更加细致的了解mxnet的运 ...
- 18年最有"钱"途的专业就是它(文末有福利)
根据社会调查机构麦可思发布的<2018年中国大学生就业报告>中得知,从就业率.薪资和就业满意度等多角度综合考量,信息安全专业为首推绿牌专业. 不管你是计算机相关专业的学生,还是已经工作的I ...
- Java线程小刀牛试
线程简介 什么是线程 现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器.堆栈和局部变量等属性,并且 ...
- 神经网络架构PYTORCH-初相识(3W)
who? Python是基于Torch的一种使用Python作为开发语言的开源机器学习库.主要是应用领域是在自然语言的处理和图像的识别上.它主要的开发者是Facebook人工智能研究院(FAIR)团队 ...
- 提纲挈领webrtc音频处理算法之写在前面的话
最近工作用到了webrtc,发现webrtc是个宝库,里面有很多东西值得好好研究. 搜了这方面不少资料,发现介绍使用webrtc的不少,但是针对里面一些算法研究的 不多.特别是能把算法说的简洁明了的更 ...