【ES6】let、var和const的区别

一直没有好好地学习ES6,最近准备从头到尾撸一遍,记录一下自己的心得。

前言:

ES5中声明变量只有两种方式:varfunction,在ES6中新增了letconst方式。它们都是去定义一个变量,当然不同的方式含义也不同。

一、const

const的中文含义是恒定的,这里你可以理解为const定义一个变量之后,它的值不可改变(这个说法不准确,后面会说到)。因为不可修改,所以声明时必须赋初始值。同时它只在声明的块级作用域之内有效,存在暂时性死区。下面是详细分析:

不可修改

const age = 23
	  age = 18  //Uncaught TypeError: Assignment to constant variable.

此时尝试修改age的值导致报错

必须给初始值

const age //Uncaught SyntaxError: Missing initializer in const declaration

未给初始值报错

不可重复声明

		const age = 18
        const age = 19 //Uncaught SyntaxError: Identifier 'age' has already been declared

重新声明已经声明过得变量报错

存在块级作用域

		{
			const age = 18
			console.log(age) //18
		}
		console.log(age) //Uncaught ReferenceError: age is not defined

大括号为age所在的块级作用域,内部调用成功,外部报错,外部未发现变量age

无变量提升

  if(true){
    console.log(age) //ncaught ReferenceError: Cannot access 'age' before initialization
	const age = 18
	console.log(age) //18
	}

未定义之前不可使用,即不存在变量提升。存在暂时性死区,即此时在age的块级作用域内,age为用const定义之前不可调用。

变量提升变量可以在声明之前使用,值为undefined

   const person = {age:22};
   console.log(person.age)//22
   person.age = 33
   console.log(person.age)//33

前面我们说到const定义一个变量之后,它的值不可改变,但是这里我们定义一个对象,里面的数据却可以被修改。const的含义是恒定的,而这里恒定并不是指const变量的值不变,而是变量的内存地址保持不变,当我们定义(数值、字符串、布尔)简单类型的数据,此时内存地址保存的保存的便是这个值所以不可改变。而当定义一个(对象、数组)时,保存的时一个指向该地址的指针,而指针指向的数据局结构时不被控制的,即可以修改。

   const person = {age:22}; 
        person = {age:22}
       console.log(person.age)//test.html:15 Uncaught TypeError: Assignment to constant variable.

此时,person重新指向了另外一个对象(两个person对象不相等,因为指针不同),此时报错

二、var

es6之前, js用var来声明变量

无块级作用域

	 if(true)
	 {
		 var age = 88
	 }
	 console.log(age)//88

if是一个块级作用域,但外部可以调用age,说明var不存在块级作用域

var分为函数作用域(局部变量)和全局作用域 (全局变量)

全局变量

    var age = 18
	function show(){
	   console.log(age) //18
	}
	show()	  
	console.log(age)//18

此时在函数外声明一个变量、函数内部和外部都可以调用,即函数外声明变量为全局变量

局部变量

	function show(){
		var age = 18
	   console.log(age)//18
	}
	show()	  
	console.log(age)//Uncaught ReferenceError: age is not defined

此时变量声明在函数内部,即只可以在当前函数内调用,此时该变量为局部变量

有变量提升

	console.log(age) //undefined	
	var age = 18

可以再变量声明前使用,但此时已声明还没赋值,所以得到undefined

重复声明

    var age = 18
	console.log(age)//18	
	var age = 20
	console.log(age)//20

可以重复声明变量

三、let

ES6新增的声明变量方式,与var类似

块级作用域

	{
		let age = 18
		console.log(age) //18
	}	
    console.log(age)//Uncaught ReferenceError: age is not defined

const一致,只在声明的块级作用域有效

变量提升

 console.log(age)//Uncaught ReferenceError: Cannot access 'age' before initialization
 let age = 18

无变量提升,不可以在声明前使用

不可以重复声明

	let age = 18
    let age = 20//Uncaught SyntaxError: Identifier 'age' has already been declared
        {
		let age = 18
		}
	    let age = 20
		console.log(age)//20

let不允许在相同作用域内,重复声明同一个变量。

暂时性死区

    var age = 18
	if(true){
		console.log(age)//Uncaught ReferenceError: Cannot access 'age' before initialization
		let age = 20
	}

只要块级作用域内存在let(const)命令,使用let(const)命令声明变量之前,该变量都是不可用的。

总结:

1、const
(1)不可以重复声明
(2)声明前必须给初始值
(3)只在声明的块级作用域内有效,外部无效
(4)不存在变量提升,即不可再声明前使用。存在暂时性死区。
(5)声明的变量不可以修改(可以修改对象,数组的数据结构)
2、var
(1)可以重复声明
(2)不存在块级作用域,是有函数和全局作用域
(3)有变量提升,可以未声明前使用,值为undefined
3、let
(1)存在块级作用域,变量只在声明块级作用域有效
(2)无变量提升,不可以在声明前使用
(3)let不允许在相同作用域内,重复声明同一个变量。
(4)暂时性死区