原生js之var let以及const的区别和作用

ES5:var
ES6:let、const

var怪异变量

首先我们要明确,var是一个块变量也叫作用域变量,如果它放到一个函数中,在函数外调用应该是失败的,在不用var a=1,这样进行定义而变成a=2,时则这个变量就变成了全局变量,如

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			function var1() {
				var a = 3
			}

			function var2() {
				b = 4
			}
			var1()
			var2()
			console.log(b)
			console.log(a)
		</script>
	</body>
</html>

在这里插入图片描述
在上述代码中,正常定义的a是报错显示a没有被定义,但是没有定义的b=4则怪异的变成了全局变量,一方面我们可以使用严格模式来定义这个函数,则会解决这个怪异问题。‘use strict’
在这里插入图片描述
同时它还有变量提升的怪异之处,我们知道,在script当中是按顺序来进行初次加载和调用的,如果我们在script全局作用域中打印出来一个a变量,那我们一定要先定义a变量再打印才能出现结果,否则就会报错,但在怪异变量中,我们如果先打印后定义不会报错,会显示undefined,就是变量已经被定义但是没有被赋值,是因为在ES当中

console.log(a);var a=1;

被等价成

var a;console.log(a);a=1;

也就是把所有的变量都拉到当前作用域的顶部,此外,多次使用var声明同一个变量也没有问题。
这就是var变量的怪异之处。而正是因为这些怪异之处,导致在ES6当中,诞生了let和const两个关键词。

let关键词

let和var的区别是,它没有var那些怪异的‘处事风格’,同时它是一个块作用域,而var是一个函数作用域

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			function let1() {
				if (true) {
					let a=1;
				}
				console.log(a)
			}
			function var1(){
				if(true){
					var a=1;
				}
				console.log(a)
			}
			var1();let1()
		</script>
	</body>
</html>

原生js之var let以及const的区别和作用_第1张图片

具体表现为,它在if-else,switch,for等定义的变量,在这些条件语句外则无法被调用,每个条件语句对它来说都是一个块,而var,只要在函数中任何地方定义,就可以在任何地方被调用。

同时在let中,也不会变量提升,在定义let变量前,不能被调用,也称为“暂时性死区”。

全局声明

在全局作用域中声明的let变量不会成为window对象的属性,而var定义的变量会,具体表现在,window.属性名出现具体值还是出现的是undefined。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			var a=1;
			console.log(window.a)
			let b=1;
			console.log(window.b)
		</script>
	</body>
</html>

在这里插入图片描述

const常量

const在初始化时必须被赋初值且不能被修改,但如果定义的是对象,修改对象中的属性的具体值,则不会报错且能修改。因为const声明的限制只是在它指向变量的引用。而具体的属性的值在修改的时候,并没有改变属性变量所在地址,所以这种改变是被允许的,但是不能改变它的属性名。举例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			const obj = {
				a: 1
			}
			obj.a = 2
			console.log(obj.a)
			obj=JSON.parse(JSON.stringify(obj).replace(/a/g, 'b')) //data为数组,name为修改前,new_name为修改后
		</script>
	</body>
</html>

在这里插入图片描述

上述例子中,我们发现当我们在const常量对象中修改属性的内容可以被修改,如果利用正则表达式修改某个属性名,则不会被修改成功。如果把const变成let则可以修改成功。
在这里插入图片描述

在大多数时候,为了避免出现代码怪异的情况,大多数开发者会选择用let和const来代替var关键词作为定义变量的主要选择,同时这样也会提升代码质量,让代码不会出现重复定义的问题和全局/作用域问题。实际const,let,var的这些属性和特征往底层实现还是要看基础的存储空间堆栈那里,这里就不多赘述了。

你可能感兴趣的:(js,web前端,javascript,前端,开发语言)