Javascript中的let和var的详细区别


在JavaScript中我们每时每刻都在声明变量、使用变量,在之前我只知道var,后面我发现同事们都在写let,我在半知半解的情况下同时使用了这两种声明方式,结果就报错了。所以在这里写一篇文档来详细说明两种声明方式的区别。

前言

在ES6中JS引入了let,在ES5之前都是使用var进行变量声明。let主要用于声明局部变量。它的用法类似于var,但是ES6也引入了块级作用域的概念,使得let命令所声明的变量只在let命令所在的代码块有效,而且有暂时性死区的约束
那么问题来了。

  • 什么是暂时性死区?
  • 什么是作用域?

var

变量提升

在了解var之前我们首先需要了解一下什么是变量提升。
下面是一道关于var变量提升的题目。

var a=99;
f();
console.log(a);
function f() {
	console.log(a);
	var a=10;
	console.log(a);
}

那么问题来了根据上面的打印输出得到的数据到底是什么呢,我相信很多人在没有了解这个机制之前都会说出是99,10,99之类的,但是实际的结果却是

undefined
10
99

为什么会这样的呢 因为当浏览器开辟出供代码执行的栈内存后,代码并没有自上而下立即执行,而是继续做了一些事情:把当前作用域中所有带var/function关键字的进行提前的声明和定义。所以实际上代码在运行到f()函数内部的时候,并没有先执行console.log,而是先执行了

var a;
//再执行
console.log(a);
//所以此时得到了undefined

接着往后走var a=10;

//此时相当于在定义var a之后给a赋值
var a;
a=10;
console.log(a);

在经过f()函数的局部变量以后,我们来到了全局变量,此时的console.log相当于执行了

var a=99;
console.log(a);

所以这就是变量提升,但是这种机制是非常的反人类的,我们都知道按部就班的执行代码是写出优秀代码的前提,这不仅给出了简洁明了的逻辑,也方便他人阅读,至此ES6,块级作用域的诞生了。

let

在ES6,JavaScript引入了let语法,不同于var声明方式的形式,let声明显得更加的严谨,在var语法中console.log(a); var a=10; 此时会得到undefined,而在let语法中console.log(a); var a=10; 此时会得到Uncaught ReferenceError:Cannot access ‘a’ before initialization,即

未捕获的引用错误:在初始化之前无法访问“a”

暂时性死区

暂时性死区存在于块级作用域,在let、const声明变量之前该变量是不能被使用的。
let、const声明变量时,该变量被绑定在这个块级作用域,不再受外部影响,不被外部访问。
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

在ES6之前,使用typeof运算符永远都是安全的,如何理解呢?就是不管对哪个变量或对象进行类型判断,typeof都是不会报错的,但是在let引入后,typeof也不再安全

typeof x; =>此时会产生ReferenceError
let x;

所以什么是暂时性死区呢,即在let定义的变量之前的块级作用域都属于x的暂时性死区

在ES6之前只有去全局作用域局部作用域的概念,在ES6引入块级作用域的概念后即可通{}来限制作用域。

{
	var x=10;
}
console.log(x);//输出10
{
	let x=10;
}
console.log(x);//ReferenceError:x not defined

具体的区别

声明后未赋值,表现相同
function(){
	var x;
	let y;
	console.log(x); //输出undefined
	console.log(y);//输出undefined
}
使用未声明的变量,表现不同
	console.log(x); //输出undefined
	console.log(y);//报错ReferenceError:Cannot access ‘y’ before initialization
	var x;
	let y;
重复声明同一个变量时,表现不同
function() {
	var x1='var first';
	let y1='let first';
	
	var x1='var second';
	let y1='let second';

	console.log(x1); //输出var second
	console.log(y1);//直接报错 Cannot redeclare block-scoped variable 'x1'
}
变量作用范围,表现不同
function(){
	var x1='var first';
	let y1='let first';
	{
		var x1='var second';
		let y1='let second';
	}
	console.log(x1); //输出var second
	console.log(y1);//输出let first,因为内部的let定义的x1是在块级作用域中是访问不到的
}

备注:使用 let 语句声明一个变量,该变量的范围限于声明它的块中。 可以在声明变量时为变量赋值,也可以稍后在脚本中给变量赋值。

使用 let 声明的变量,在声明前无法使用,否则将会导致错误。

如果未在 let 语句中初始化您的变量,则将自动为其分配 JavaScript 值 undefined

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值