Let:用来声明变量,但是所声明的变量,只在let命令所在的代码块内生效。
变量提升:变量可以在声明之前使用,值为undefined。
暂时性死区:在代码块内,使用let命令声明变量之前,该变量都是不可用的。
不允许重复声明:let不允许在相同作用域内,重复声明同一变量。
Const:const声明一个只读的常量。一旦声明,常量的值就不能改变,一旦声明变量,就必须立刻初始化,不能留到以后赋值。
Const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
基本数据类型:number、string、boolean、undefined、null、symbol、BigInt,七类。
引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象。)
栈(stack):自动分配的内存空间,它由系统自动释放。
堆(heap):动态分配的内存,大小也不一定会自动释放。
基本数据类型(存放在栈中):基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以分配,他们是直接按值存放的,所以可以直接按值访问。
引用数据类型(存放在堆内存中的对象,每个空间大小不一样,要根据情况进行特定的配置)
引用类型是存放在堆内存中的对象,变量其实是保存的再栈内存中的一个指针(保存的是内存中的引用地址),这个指针指向堆内存。引用类型数据在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存在堆内存中的对象。
基本数据类型和引用数据类型的区别
1:声明变量时内存分配不同
原始类型:在栈中,因为占据空间是固定的,可以将他们存在较小的内存中-栈中,这样便于迅速查询变量的值。
引用类型:存在堆中,栈中存储的变量,只是用来查找堆中的引用地址。
这是因为:引用值得大小会改变,所以不能把它放在栈中,否则会降低变量查询的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中堆变量性能无任何负面影响。
2:不同的内存分配带来不同的访问机制
在js中是不允许直接访问保存在堆内存中的对象的,所以在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值,这就是按引用访问。而原始类型的值是可以直接访问到的。
3:复制变量时的不同
原始值:在将一个保存着原始值的变量复制给另一个变量时,会将原始值得副本赋值给新变量,此后这两个变量是完全独立的,他们只是拥有相同的value而已。
引用值:在将一个保存着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量,也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的改变都会反映在另一个身上。多了一个指针而已。
4:参数传递的不同(把实参复制给形参的过程)
Es中所有函数的参数都是按值来传递的,
原始值:只是把变量里的值传递给参数,之后参数和这个变量互不影响。
引用值:对象变量它里面的值是这个对象在堆内存中的内存地址!因此它传递的值也就是这个内存地址,这也就是函数内部对这个参数进行修改会提现在外部的原因,因为他们都指向同一个对象。