关于const,let,var是一个再基础不过的问题了,然而就这基础的问题,总是没法在脑海里去形成一个体系的记忆。所以从今天开始,应该每天都要保持总结一个小点的习惯,来形成自己的知识体系。 说起var 与 let,const。首先对它的归类,我们需要知道 var 属于 es5 const let 属于 es6 下面就正式开始! 区别一:变量提升
在es5版本的项目,我们随处可以看见var的关键字,无论需要定义什么,一个var就搞定了,js弱语言的特性,使之会帮你判断定义的变量是一个什么样的基本类型。 es5版本,var与fuction关键字是存在变量提升的。js的引擎运行规则是,先解析代码,获取声明的变量,然后再一行一行的运行代码。被var定义的变量,会被提升到代码的头部,这时候就形成了变量提升,使之变量或者函数在未被声明之前,先使用不会出错。比如说:
var x = 1; // 声明 + 初始化 x console.log(x + " " + y); // '1 undefined' var y = 2;那这相当于:
var x = 1; var y = 2; console.log(x + "" + y);但是如果是换成let(换成const是相同的道理)
let z = 1; console.log(z + "" + r); let r = 3; // r is not defined也就说明,let,const是不存在变量提升的。在我看来,let,const更加符合代码从上至下的逻辑,也规范了代码的书写,在es6语法中,let,const就是用来取代var变量的。 区别之二:作用域 对于var而言,只有全局作用域和函数作用域。我们常说的局部作用域其实是指,变量在函数内则为局部作用域,那么该变量只能在函数内访问。如果变量不在函数内,则为全局变量。html中全局变量的作用域范围为windows(虽然我们平常很少用windows去点出来) 在es6之是没有块级作用域这么一说的。在es6中是存在的。 在我理解看来,var与const,let其实是少了块级作用域这么一说的。比如说:
{ var a = 1; } // 那么在这里应该不可以访问到a,可是这里可以,说明var是没有块级作用域这么一说的。 { let a = 1; } // 这里不可以访问的,说明{}中,let定义的变量是受保护的。当然说到了作用域,又不得不提到循环作用域。因为这个概念,又提到了立即执行函数的概念。 比如说:
var i = 5; for (var i = 0; i < 10; i++) { // 一系列的代码 } console.log(i); // 此时i为10;因为var定义的变量是全局的,循环体内与外,都会受到影响的。 而对于let而言,又有如下的结果:
let i = 5; for ( let i = 0; i < 10; i ++) { // 一系列的代码 } console.log(i); // 此时i为5,可见,let对于局内与局外没有什么影响区别之三:重新定义变量 使用var重新声明变量可能会带来问题,比如说在块级作用域去修改var定义的变量,那么可能会把全局的值给修改了。比如说:
var x = 10; { var x = 2; } // 这里输出x为2,如果存在相同的变量,及有可能把变量给误修改了但是对于let而言,因为存在块级作用域,所以,重新定义变量,它的逻辑会比较清晰。
// 这里输出x为10 { let x = 2; // 这里输出x为2 } // 这里输出x为10当然,是用var定义的常量不可以再用let去声明了,这不符合规范。 注意,使用var,let我们都可以声明一个变量,可以不用给初始值。但是如果用const定义只能定义常量(不可修改),且必须有初始值。 比如说:
const a; a = 1; console.log(a) // SyntaxError: Missing initializer in const declaration那么这个a在这里是不符合规范的。 又比如说:
const a = 1; a = 2 console.log(a); //TypeError: Assignment to constant variable.这也是不符合规范的,因为a使用const定义的常量,不可以再修改的。 但是如果是用const定义的对象,再去修改,会变成
const a = {}; a.x = '1' console.log(a); // { x: '1' }原因是因为const定义的对象,对象的指向地址并没有改变,const能保证的就是指针不改变,并不影响指向的内容。所以,使用const还是可以改变对象的。