javascript中声明变量的var、let和const
区别
提示:这里以javascript中为例子:
var声明的变量会挂载在windows上,而let和const声明的变量不会。var声明的变量存在变量提升,let和const不存在变量提升。同一作用域下var可以声明同一变量名,let和const不可以。let和const声明会形成块作用域,let暂存死区,const一旦声明必须赋值,不能用null占位,声明后不能再修改,但可以修改属性。
一、var和let
提示:在同一作用域下,var可以声明同一变量而不报错,let声明同一变量就报错。:
代码如下(示例):
<body>
<script>
var a = 1;
var a = 5;
console.log(a);
</script>
</body>
运行结果是a=5;即后面的赋值覆盖前面的值。在同一作用域下,let则不允许,let只能在不同的作用域才可以声明同一变量。
<script>
let a = 1;
function fn1(){
let a = 3;
console.log(a);
}
fn1();
console.log(a);
</script>
它在控制台打印为:3,1
二、变量提升
1.预解析
代码如下(示例):
我们Js引擎运行js分为两步:
1、预解析
2、执行代码
预解析会把我们声明变量提升到代码最上方,而当遇到function函数声明时它具有优先的变量提升,做几个练习:
1、第一个例子,我们一开始声明了a=1,代码运行到fn()函数被调用的时候,执行函数代码,此时函数内的变量a并没有声明,它会找到函数外的全局变量var a;此时函数内把2赋给a,所以函数打印a的值是2。由于修改了a的值,它又是全局变量,所以第二次打印a的值仍然是2.
<script>
var a = 1
function fn(){
a = 2
console.log(a);//2
}
fn()
console.log(a);//2
</script>
2、第二个例子,在练习一的基础上,在函数fn()中增加声明变量a的代码。函数内一开始console.log(a),此时预解析将var a;提升到最上方,所以此时控制台不会报错,a的值是undefined。由于函数内有声明,故函数内为局部变量,不会干扰函数外变量a的值,所以第三次打印a的值是1。
<script>
var a = 1
function fn(){
console.log(a);//undefined
var a = 2
console.log(a);//2
}
fn()
console.log(a);//1
</script>
3、第三个练习,给函数fn()中传递一个形参a,定义形参就相当于在函数中声明了对应的变量,但是没有赋值。所以虽然函数内取消了var a;但由于定义了形参,所以运行结果跟第二个练习一样。如果给a传一个实参,就把值传进去。
<script>
var a = 1
function fn(a){
console.log(a);//undefined
a = 2
console.log(a);//2
}
fn()
console.log(a);//1
</script>
<script>
var a = 1
function fn(a){
console.log(a);//10
a = 2
console.log(a);//2
}
fn(10)
console.log(a);//1
</script>
4、第四个练习,函数fn()传一个实参a,此时a的值是全局变量声明的1,但由于参数是传进函数里,即使将2赋给a,也不影响全局变量a=1。
<script>
var a = 1
function fn(a){
console.log(a);//1
a = 2
console.log(a);//2
}
fn(a)
console.log(a);//1
</script>
5、第五个练习,代码如下,预解析的时候产生了var a;和函数function a()的变量提升,函数在这两者之中优先,所以第一次打印a的值就是函数中的alert(2),在下面也就不再执行该函数。
<script>
console.log(a);//alert(2)
var a = 1
console.log(a);//1
function a() {
alert(2)
}
console.log(a);//1
var a = 3
console.log(a);//3
var a = function(){
alert(4)
}
console.log(a);//alert(4)
a = 5
console.log(a);//5
</script>
三、let和const
提示:let和const在使用时,应考虑变量是否可变:
1.数据类型
数据类型分为简单数据类型和复杂数据类型;
简单数据类型(Number,String,Boolean,Underfined,Null)
复杂数据类型(object,Array,Date)
Number 数字型,包含整型值和浮点型值,如21、0.21 ,默认值:0;
Boolean 布尔值类型,如true、false,等价于1和0,默认是:false;
String 字符串类型,如“张三” 注意咱们JS里面,字符串都带引号,默认值:“”;
Undefined var a;声明了变量a但是没有给值,此时a = undefined,默认值:undefined;
Null var a = ull;声明了变量a为空值,默认值:null;
2.数据类型存储方式
简单数据类型存储在栈中,先将变量的声明在内存中的栈开辟一片空间值是undefined,复杂数据类型则在栈中有一个地址,再由这个地址指向堆中的属性值,以数组为例,如下图:
3、根据数据类型选用let和const
建议数组和对象使用const声明(默认数组、对象不再改变,变的是属性的值),当变量需要改变时,使用let声明,比如for循环中i的值(i++或i–)。
因此,一般可以先用const声明,发现变量可变时,再改用let。