前世在 const & let 还未出现前,JS 的世界一直是 var的统治var:在JS中用于变量声明的关键字。特点:变量提升只有函数作用域或者全局作用域,没有块级作用域重复声明变量循环体重的闭包会出现问题…….变量提升function test(tag) { console.log(a,b); // a,b在下面声明,但是会打印出undefined,不会报错 if(10 >= tag) { var a = tag + 1; } else { var b = tag - 1; }}在浏览器预解析机制中,加载函数的时候,此时的作用域为函数作用域,函数作用域中JS会先将所有的声明置顶。function test(tag) { var a,b; // 将声明置顶,但是赋值并不会 console.log(a,b); // a,b在下面声明,但是会打印出undefined,不会报错 if(10 >= tag) { var a = tag + 1; } else { var b = tag - 1; }}只有函数作用域以及全局作用域,没有块级作用域function test(tag) { console.log(a,b); // a,b在下面声明,但是会打印出undefined,不会报错 if(10 >= tag) { var a = tag + 1; } else { var b = tag - 1; } console.log(a); // 9}test(8) // 9按照其他语言规则 if 是一个程序块,在 if 中声明的变量作用域只能在 if 中,但是 JS 因为只有函数作用域和全局作用域,所以才会导致在 if 判断外还可以访问 if 的变量重复声明变量var a = 1;var a = 2;console.log(a); // 2在使用var的时候允许重复声明变量也是令人头痛的事情,也许因为这个机制,可能就会出现bug循环体重的闭包会出现问题var arr = [];for(var i = 0; i < 3; i++) { arr.push(function () { return i; })}for(var j = 0; j < 3; j++) { console.log(arrj); // 3,3,3}将var -> let将会打印出 0,1,2因为缺乏块作用域所以导致问题出现今生如今距离ES6规范的出现已经过去了4年多了,在项目中也早已开始大量使用ES6规范编写代码了。var也不再是JS世界的唯一了,JS 世界出现了const & let。const & let 的出现给JS带来了块级作用域,解决了变量提升,禁止了重复声明变量,让JS少了很多疑惑的地方。let & const相同点:具有块级作用域禁止重复声明变量不会产生变量提升区别:let使用let声明的基本类型变量是可以改变值let a = 12;a = 13;return a; // 13使用let声明引用类型的变量是可以改变引用的let info = { name: “ming995”, age: 25, sayHi: function() { console.log(Hi I'm ${this.name}) }};let heInfo = {};heInfo = info;heInfo.name = “Jack”;console.log(heInfo);const使用const声明的基本类型变量是不可以改变值const a = 13;a = 14;return a; // 报错使用const声明引用类型的变量是不可以改变引用的const info = { name: “ming995”, age: 25, sayHi: function() { console.log(Hi I'm ${this.name}) }};const heInfo = {};heInfo = info; // 报错 heInfo.name = “Jack”;console.log(heInfo);但是我们可以操作const声明的引用类型的属性值const info = { name: “ming995”, age: 25, sayHi: function() { console.log(Hi I'm ${this.name}) }};info.language = “js”;console.log(info);总结之前对于const的理解有偏差,所以就写这篇文章。var时代已经过去了,ES6各种特性用起来。