JS中的var,let,const的区别和使用

在ES5中,只能通过var来声明变量,而且对变量作用域的规定不是很清晰,这带来了很多问题。于是在ES6中引入了let和const来改进var,这一节我们来用实例看看这三者在声明变量时候的一些区别。

文章目录

var

用var来声明一个变量是很简单的,不过var声明的变量只有两种作用域,全局或者函数内

例如下面这段代码

var a = 'xiaofu';
console.log(a);

function test(){
	var a = 'zhangsan';
	console.log(a);
};

test();
console.log(a);

因为函数内定义的变量会在函数内覆盖全局的变量,所以最后的打印结果为

xiaofu
zhangsan
xiaofu

看似没什么大问题,但是下面两种情景结果就可能会不符合预期

第一种,函数内变量提升

JS处理一段代码,是先对一个作用域中的所有变量声明部分进行处理,然后再处理其他部分,并不是严格地从上到下。于是出现了个叫变量提升(hoisting)的概念,也就是在一个作用域中的变量使用在声明之前也并不会报错。例如函数也是一种变量,函数的定义不管在哪个位置,使用该函数的时候可以在该作用域的任意位置。但是,变量提升仅仅是对变量的声明,不包括初始化,所以对普通的变量,在初始化前使用虽然不会报错,但是值会返回undefined

看上面那段代码稍微修改下

var a = 'xiaofu';

function test(){
	console.log(a);
	var a = 'zhangsan';
	console.log(a);
};

test();

本意是先打印全局变量,然后打印函数内变量。但是因为在函数内有变量提升,所以第一次打印的时候并不会打印全局的变量a,而是函数作用域的a

undefined
zhangsan

第二种,循环变量泄露

看下面这段代码

for(var i=1;i<5;i++){
}
console.log(i);

打印结果为

5

本来是作为计数使用的变量i被泄露成了全局变量,这也不是我们所期望的。

let

于是ES6中引入了let来解决上面的这两个问题。

首先,用let声明的变量没有了变量提升

用let声明的变量必须遵守先声明再使用的顺序,否则报错

console.log(a);
let a = 'xiaofu';

像这种之前会打印undefined的,现在会有如下报错

Uncaught ReferenceError: Cannot access 'a' before initialization

那么像下面的代码结果如何呢?

let a = 'xiaofu';

function test(){
	console.log(a);
	let a = 'zhangsan';
	console.log(a);
};

test();
console.log(a);

还是会报和上面一样的错误。

要注意的是,在块级作用域内不管任何位置用let声明了一个变量,这个变量就和这块作用域绑定了,不受外面变量的影响。所以在第一次打印的时候还是指向局部变量a,因为使用在声明之前所以报错。这种现象称之为暂时性死区(temporal dead zone, TDZ)。

所以不管是全局变量还是局部变量,都要先声明再使用,尽量不要用同名变量

然后,let声明的变量只在声明的块内有效

这么说比较模糊,我们只需要知道小括号内声明的变量不会泄露为全局变量了,例如循环中的计数变量

let i = 'xiaofu'
for(let i=1;i<5;i++){
}
console.log(i);

最后会打印

xiaofu

如果没有前面的let i = 'xiaofu',就会报错

Uncaught ReferenceError: i is not defined

所以,ES6以后变量尽量用let来进行声明,会更严谨一点,避免一些不符合期望的结果。

const

const用于声明一个常量,该常量在后面的使用中不可以被修改。这里要注意,对于复合类型的数据,也就是object和array类型,只能保证该变量不能被重新赋值,该变量的内容还是可以修改的。

const test='xiaofu';
test='jason';

会报错

Uncaught TypeError: Assignment to constant variable.

但是

const test=['xiaofu'];
test.push('jason');
console.log(test);

就会正常打印

["xiaofu", "jason"]

如果想让object和array也完全不可以被修改,可以用Object.freeze()方法

const test=Object.freeze(['xiaofu']);
test.push('jason');
console.log(test);

会报错

Uncaught TypeError: Cannot add property 1, object is not extensible

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值