JavaScript,var和let到底有啥区别?
发布于 作者:苏南大叔 来源:程序如此灵动~
本文描述前端经典面试题目:var和let的区别。通过前面两篇文章的描述,大家已经大体知道了var和let在实际的编程中,其实是有区别的。那么,区别究竟是什么呢?本文中,苏南大叔做个总结。

苏南大叔单独对var和let进行过阐述,建议您先看看苏南大叔以前写的两篇相关文章,那么会对本文产生更深刻的理解的。本文测试环境:win10,chrome@89.0.4389.114。
系列文章
本文是系列文章第三篇:
- 《js中的var作用域是如何生效的?》 https://newsn.net/say/js-var.html
- 《js中的let作用域是如何生效的?》 https://newsn.net/say/js-let.html
- 《var和let到底有啥区别》 https://newsn.net/say/js-var-vs-let.html
- 《再次举例对比let和var的区别,为什么使用let》 https://newsn.net/say/js-var-vs-let-2.html
相同点:函数作用域范围内都不影响全局变量
结论:函数作用域里面的var和let都没有改变全局变量。
函数作用域下的var就是个局部变量,是不会改变全局的。而let本身的定义,就是作用在一个最小的作用域里面的。所以,更不会改变函数作用域范围外的全局变量了。
测试代码如下:
var a="苏南大叔";
let b="北京大学";
(function(){
var a="苏南大叔最棒";
let b="北京大学还行";
console.log(a,b);
})();
console.log(a,b);
但是,如果在函数作用域内不写var或者let字样的话,默认就是修改全局变量了。比如下面的代码:
var a="苏南大叔";
let b="北京大学";
(function(){
a="苏南大叔最棒";
b="北京大学还行";
console.log(a,b);
})();
console.log(a,b);会得到一个完全不同的答案,见下图所示:

区别一:块级作用域内是否会影响全局
结论:块级作用域的var改写了全局变量,而let并没有改变全局。
传统的作用域包括:全局作用域、函数作用域两种。这里需要先普及一个概念,啥叫"块级作用域"。这个概念是es6里面提出来的。在es6里面提出了一个新的概念,叫做块级作用域。比如:{},或者是if语句或者是for语句里面的{}。
测试代码:
var a="var";
let b="let";
{
var a="var块级作用域";
let b="let块级作用域";
console.log(a,b);
}
console.log(a,b);运算结果:
区别二:是否允许先使用后定义
结论:首先要区别是不是严格模式,
如果是严格模式,那么一个变量是肯定不可以不定义就使用的,这个和是var还是let是没有关系的,这里不做复述。
而在非严格模式下,var是不关心是先使用还是先定义的,使用模式是非常宽松的。而let则是非常严谨的,只要let出场的作用域范围内,都不允许未定义先使用。
报错如下:
Uncaught ReferenceError: Cannot access 'b' before initialization可以参考下面的代码:
a="a";
b="b";
var a="var";
let b="let";运行结果如图所示:
区别三:同一个作用域范围内是否允许重复定义
结论:在同一个作用域里面,var重复定义并不会报错,而let重复定义会报错。
参考代码如下:
var a="a";
let b="b";
{
var a="var";
let b="let";
var a="var2";
let b="let2";
}重复let定义,报错如下:
Uncaught SyntaxError: Identifier 'b' has already been declared截图如下:

相关链接
当然,本文中的内容和网上流传的标准答案肯定是不一样的,因为这里面增加了苏南大叔自己的理解嘛。所以,你要是在考试,就别抄袭本篇文章的内容了,这并不是标准答案。标准答案应该是:let不影响全局作用域,var可以影响全局作用域,变量会提升。
var和let,连起来是varlet,英文意思是:无赖,恶棍。不过,目前为止,苏南大叔还没有见过谁这样用过...
总结
整体上来说,如果给var和let拟人化的话,var就是个很随和的性格,而let则是个非常谨慎的性格。不晓得,你感受到了没有?更多js相关基础知识,请参考苏南大叔的博客: