一、let
1、let声明的变量只能在所处的块级作用域有效
if(true){
let a=10; //let定义a变量
console.log(a); // 10
}
console.log(a); //a没有被定义
这里的一个块级作用域就是这if大括号内
注意在定义变量的时候 (无论是var,let还是const) ,都尽量都要先赋初始值,因为如果不赋初始值那么 undefined与任何数字进行加减乘除的时候结果都为NAN
2、let声明的变量不存在变量提升
不了解变量提升的小伙伴可以去https://blog.csdn.net/weixin_42397257/article/details/89147206
3、let声明的变量存在暂时性死区
var num=10;
if (true){
console.log(num); //报错,未声明变量
let num=20; //let声明的变量会与它所在的块级作用域进行绑定
}
举个例子:
var arr=[];
for (let i=0;i<3;i++){ //i的作用域是for循环内
arr[i]=function () {
console.log(i);
}
}
arr[0]();
arr[1]();
arr[2]();
解释解释这里:每一次for循环会产生一个块级作用域,而每一个块级作用域里面的i有不同的值,所以每一个函数在调用的时候都在其对应的作用域内查找i的值
二、var
1、使用var声明的变量不具有块级作用域
if(true){
var a=10; //var定义a变量
console.log(a); // 10
}
console.log(a); // 10
for (var i=0;i<10;i++); //在循环体内的i
console.log(i); //在循环体外的i,输出为10
举个栗子:
var arr=[]; //arr和i都是全局变量
for (var i=0;i<3;i++){
arr[i]=function () {
console.log(i);
}
}
arr[0]();
arr[1]();
arr[2]();
为什么会这样呢,说说我的理解:i是个全局变量,且函数里面的i是在调用的时候进行赋值的,而当for循环完成的时候i=3,使用输出结果都是3
当然这里可以使用闭包来实现let的效果(因为函数是有作用域的)
for (var i=0;i<3;i++){
(function (i) {
arr[i]=function () {
console.log(i);
}
}(i))
}
2、var存在变量提升
这大家都了解,就不赘述了
三、const(声明常量,内存地址不变的量)
1、拥有块级作用域
if(true){
const A=10; //A有块级作用域
console.log(A);
}
console.log(A); //访问不到A
2、const声明常量的时候必须赋初始值
3、常量赋值后值(内存地址)不可改变
const A=10;
// A=20; 这里的A不可修改
console.log(A);
const Arr=[10,20];
Arr[0]=30;
Arr[1]=40;
//Arr=[50,60] 这样是不允许的,改变了Arr地址
console.log(Arr); //Arr的值没有修改,而修改了值(地址)对应的值
const Obj={
name:'小明',
age:10
};
Obj.name='小华';
Obj.age=20;
console.log(Obj); //Obj的值没有修改,而修改了值(地址)对应的值
这里的修改值是没有修改常量的值(地址),而是修改了值的地址里面的值
本文只用于个人学习和记录